zoukankan      html  css  js  c++  java
  • 博客作业2---线性表

    博客作业2---线性表

    一、PTA实验作业(5分)

    题目1: jmu-ds- 顺序表删除重复元素

    2. 设计思路(伪代码或流程图)

    新建顺序表函数:
    应用地址L,传入数组a【】和长度n
    L申请空间
    定义变量i
    for(i=0;i<n;i++)
        将数组a中元素转移到L中
    L的长度改为n
    
    展示表中元素函数:
    传入顺序表L
    定义变量i
    for(i=0;i<L->length;i++)
        输出L->data[i]
        不到最后一个元素都输出空格
    
    删除相同元素函数:
    引用顺序表L
    定义变量i,j,k
    for(i=1;i<L->length;i++){
        for(j=0;j<i;j++){
            if(L->data[i]==L->data[j])找到相同元素
    		移动后面元素删除相同元素
    		L长度减少
    		i--,从该位置开始判断
        end
    end
    

    3.代码截图

    4.PTA提交列表说明。


    该题提交结果提交时,只出现了段错误,没有其他的错误,一直找不到原因,一直修改删除相同数据的函数,不断提交,结果最多就只有空表的数据点正确。
    解决方法:看了一眼其他同学的代码,发现新建顺序表时,没有给L申请空间,但是devc++编译没出现问题,所以一直没发现,修改后就对了。

    题目2:jmu-ds-单链表逆置

    2. 设计思路(伪代码或流程图)

    新建单链表函数:
    应用地址L,传入长度n
    新建指针p和tail
    L申请空间
    初始化L为空的单链表
    tail赋值L,形成尾指针
    定义int变量num存元素
    while(n--)
        输入num
        p节点申请空间
        p->data变为num
        p->next为空
        连接p与L
        尾节点移动到p
    end
    
    展示表中元素函数:
    传入单链表L
    定义指针l进行链表间移动
    if(L为空链表)输出NULL
    while(l不为空)
        输出l->data
        不到最后一个元素都输出空格
        l移动到下一个节点
    end
    
    单链表逆序函数:
    引用单链表L
    定义List指针p=L->next得到L的后续节点,并定义一个q暂存节点
    L链表初始化为空
    while(p不为空时)
        q从p中取出一个节点
        p移动到下一个
        q节点为插到L的后面
    end
    

    3.代码截图


    4.PTA提交列表说明。


    思路清晰,在devc++上验证好多遍,上交后有一个错误:空表时格式错误,结果是因为输出时没检查空表,加上一句判断后结果正确。

    题目3:集合的基本运算

    2. 设计思路(伪代码或流程图)

    新建单链表函数:
    应用地址L,传入长度n和数组a
    新建指针p和tail
    L申请空间
    初始化L为空的单链表
    tail赋值L,形成尾指针
    定义变量i
    for(i=0;i<n;i++)
        p节点申请空间
        将数组a中元素转移到p->data
        p->next为空
        连接p与L
        尾节点移动到p
    end
    
    展示表中元素函数:
    传入单链表L
    定义指针l进行链表间移动
    if(L为空链表)输出NULL
    while(l不为空)
        输出l->data加空格
        l移动到下一个节点
    输出换行
    end
    
    摧毁单链表函数:
    引用L
    定义链表指针p
    while(L)
        p=L
        L下移
        删除p
    end
    
    排序的函数:
    引用L
    定义链表指针p继承L后续节点,q存放取出的节点,l在新建链表上移动,pre用于连接
    L->next=NULL
    while(p)
        q=p取出节点
        p下移
        if第一个节点,直接插入
        else
            pre=L
            l=L->next
            while(l不为空)
                if(l->data大于q->data)
                    插入q在该元素前面
                    停止循环
                if(l到达尾)
                    q直接插到末尾
                    停止循环
                l指向下一个
            end
    end
    
    求并集的函数:
    传入ha,hb,引用hc
    定义链表指针p和tail当成尾节点
    hc申请空间并初始化
    尾节点初始化到hc
    ha=ha->next;hb=hb->next从有效点开始操作
    while(ha||hb)两条链表都结束才结束
        p申请空间
        if(hb为空或ha->data小于hb->data)
            ha的data给p的data
            p->next为空
            连接p到hc
            ha移动到下一个
        else if(ha为空或ha->data大于hb->data)
            hb的data给p的data
            p->next为空
            连接p到hc
            hb移动到下一个
        else if(ha->data等于hb->data)
            hb的data给p的data
            p->next为空
            连接p到hc
            ha,hb移动到下一个
    end
    
    求交集函数:
    传入ha,hb,引用hc
    定义链表指针p和tail当成尾节点
    hc申请空间并初始化
    尾节点初始化到hc
    ha=ha->next;hb=hb->next从有效点开始操作
    while(ha||hb)两条链表都结束才结束
        p申请空间
        if(hb为空或ha->data小于hb->data)
            ha移动到下一个
        else if(ha为空或ha->data大于hb->data)
            hb移动到下一个
        else if(ha->data等于hb->data)
            hb的data给p的data
            p->next为空
            连接p到hc
            ha,hb移动到下一个
    end
    
    求差集函数:
    传入ha,hb,引用hc
    定义链表指针p和tail当成尾节点,h存ha和hc交集
    h申请空间并初始化
    调用函数求ha和hc交集到h
    hc申请空间并初始化
    尾节点初始化到hc
    ha=ha->next;h=h->next从有效点开始操作
    while(ha||h)两条链表都结束才结束
        p申请空间
        if(h为空或ha->data小于h->data)
            ha的data给p的data
            p->next为空
            连接p到hc
            ha移动到下一个
        else if(ha为空或ha->data大于h->data)
            h的data给p的data
            p->next为空
            连接p到hc
            h移动到下一个
        else if(ha->data等于hb->data)
            ha,hb移动到下一个
    end
    

    3.代码截图





    4.PTA提交列表说明。


    开始的错误有段错误和答案错误,多错误的原因就是空指针是让他指向了data,修改了循环和一些条件就可以了,改动的地方很多很杂,不便具体指出,然后就是答案错误,具体原因是求差集的函数理解错误,以为是a并b-a交b,结果是a-b,理解后改了下就对了。

    二、截图本周题目集的PTA最后排名(3分)

    1.顺序表PTA排名

    2.链表PTA排名

    3.我的总分:270

    三、本周学习总结(2分)

    1.谈谈你本周数据结构学习时间是如何安排,对自己安排满意么,若不满意,打算做什么改变?(1分)

    学习时间都是预习作业一出来就开始本章的预习,先翻翻课本了解一下,在通过课堂派的习题深入了解知识点,等到真正上课时认真听老师讲解本章的知识点,稍微记录下老师讲过的但课本上没有的重要内容,最后通过pta综合一下,融会贯通,能熟练运用于实践的代码编程。编程的时间安排一般是找时间比较长的时间段,不如晚自习放学回宿舍,或礼拜天,一起做几题出来,一般一个时间段能做三四题。不懂问题时一般先在宿舍内讨论下,基本能得到解决。安排还算满意,能够保持下去就可以了。

    2.谈谈你对线性表的认识?(1分)

    线性表就是将一串数据连接起来成线性结构,方便对这串数据进行操作的一种结构.
    线性表主要主要有两种存储结构:顺序结构和链式结构
    1.顺序结构/顺序表
    顺序表在计算机内占有一块连续的内存,可以通过下标直接访问到表中元素,但是删除表中元素时就要对其他元素做移动。
    结构体定义样例:

    struct LNode {
        ElementType Data[MAXSIZE];
        Position Last; /* 保存线性表中最后一个元素的位置 */
    };
    

    基本操作合集:

    //销毁顺序表 
    void FreeList_sq(SqList &L){  
        if (L.elem)   
        free(L.elem);  
        printf("完成链表内存销毁
    "); 
    }    
    //在顺序表的第i个位置之前插入新元素 
    int ListInsert_sq(SqList &L, int i, ElemType e){  
        int k;  
        if (i<1 || i>L.length + 1) 
            return ERROR; /*插入位置不合法*/  
        if (L.length >= L.listsize){     /*存储空间满,重新分配空间*/   
            L.elem = (ElemType*)realloc(L.elem, (LIST_INIT_SIZE + INCREM)*sizeof(ElemType));   
            if (!L.elem) return OVERFLOW;      /*存储分配失败*/   
                L.listsize += INCREM;             /*修改存储空间大小*/  
        }  
        for (k = L.length - 1; k >= i - 1; k--){      /*插入位置之后元素后移*/   
            L.elem[k + 1] = L.elem[k];  
        }  
        L.elem[i - 1] = e;                     /*插入元素*/  
        L.length++;                         /*顺序表长度加1*/  
        return OK; 
    }/*ListInsert*/    
    //遍历并输出顺序表所有元素 
    void PrintList_sq(SqList &L){  
        if (!L.elem)   return;   
        int i = 0;      
        for (i = 0; i < L.length; i++)   
            printf("第[%d]元素= [%d]
    ", i, L.elem[i]); 
    }   
    //删除顺序表第i个位置的元素  
    int ListDelete_sq(SqList &L, int i,ElemType &e){  
        int k;  
        if (i<1 || i>L.length) 
        return ERROR; /*删除位置不合法*/  
        e = L.elem[i-1];  
        for (k = i - 1; k<L.length - 1; k++)       /*元素前移*/   
            L.elem[k] = L.elem[k + 1];  
            L.length--;                       /*顺序表长度减1*/  return OK; 
    }   
    //在顺序表里查找出第1个与e相等的数据元素位置 
    int LocateElem_sq(SqList L,ElemType e){ 
         int i = 0;  
        while(i<=L.length){   
            if(L.elem[i] == e)     
                break;   
            else    
                i++;  
        }  
        if(i<=L.length) 
            return i;  
        return -1; 
    }   
    //已知线性表La和Lb的元素按值非递减排列  //归并后的La和Lb得到新的顺序线性表Lc,Lc的元素也是按值非递减排列 
    void MergeList_sq(SqList La,SqList Lb, SqList &Lc){  
        ElemType *pa = La.elem;  
        ElemType *pb = Lb.elem;  
        Lc.listsize = Lc.length = La.length + Lb.length;   
        if(!Lc.elem) exit(OVERFLOW); //存储分配失败  
        int i = 0,j = 0;   
        int k =0;    //i指向La的当前位置,j指向Lb当前位置,k指向Lc当前位置  
        while(i<La.length && j<Lb.length){   //归并   
            if(La.elem[i]<Lb.elem[j]){     
                Lc.elem[k] = La.elem[i];    
                i++;   
            }   
            else{    
                Lc.elem[k] = Lb.elem[j];    
                j++;   
            }   
            k++;  
        }  
        while(i<La.length) 
            Lc.elem[k++] = La.elem[i++];  
        while(j<La.length) 
            Lc.elem[k++] = Lb.elem[j++];   
    }
    //判断顺序表是否为空
    bool ListEmpty(SqList &L){ 
        if(L.length > 0)  
            return 1;  
        else   
            return 0; 
    }
    

    2.链式结构/单链表,双链表,循环链表
    链表存储更叫灵活,不依赖物理上内存的位置,可以进行任意的增加和删除,即增加减少节点即可,但是查找时这要遍历链表方能找到。
    结构体定义:

    typedef char ElemType;
    typedef struct LNode	//定义单链表结点类型
    {
      ElemType data;
      struct LNode *next;
    } LinkList;
    

    基本操作集合:

    //销毁单链表表  
    void FreeList_L(LinkList L){   
        LinkList p = L;  
        while (p){   
            L = L->next;   
            free(p);   
            p = L;  
        }  
    }    
    //在单链表的第i个位置之前插入新元素  
    Status ListInsert_L(LinkList &L, int i, ElemType e){  
        LinkList p = L;   
        int j = 0;  
        while(p && j<i-1){  //寻找第i-1个结点   
            p = p->next;   
            ++j;  
        }  
        if(!p || j>i) 
            return ERROR;  
        LinkList s = (LinkList)malloc(sizeof(LNode));  
        s->data = e;  
        s->next = p->next;  
        p->next = s;  
        return OK; 
    }     
    //遍历并输出单链表所有元素 
    void PrintList_L(LinkList L){  
        int i = 0;  
        LinkList p = L->next;  
        while (p){   
            printf("第[%d]元素= [%d]
    ", i++, p->data);   p = p->next;  
        }   
    }  
    //获取单链表第i个位置的元素  
    Status GetElem_L(LinkList L,int i,ElemType &e){  //L为带头结点的单链表的头指针  
    //当第i个元素存在,其值赋给e并返回OK,否则返回ERROR  
        LinkList p = L->next;  
        int j = 1;  
        while(p && j<i){   
            p = p->next;   
            ++j;  
        } 
         if(!p) 
            return ERROR; //第i个元素不存在  
        e = p->data;  
        return OK; 
    }   
    //删除单链表第i个位置的元素,并由e返回其值 
    Status ListDelete_L(LinkList &L, int i, ElemType &e){  
        LinkList p = L;   
        int j = 0;  
        while(p->next && j<i-1){  
            //寻找第i个结点,并令p指向其前驱   
            p = p->next;   
            ++j;  
        }  
        if(!p->next || j>i-1) 
            return ERROR;  //删除位置不合理  
        LinkList q = p->next;  
        p->next = q->next;  
        e = q->data;  
        free(q);  
        return OK;  
    }   
    //单链表翻转,不增加额外的存储空间 
    void ListConvert_L(LinkList &L) {  
        LinkList p,q;  
        p=L->next;  
        L->next=NULL;  
        while(p){   
            q=p;   
            p=p->next;   
            q->next=L->next;   
            L->next=q;  
        } 
    }
    

    3.代码Git提交记录截图

    四、阅读代码(选做,加1分)

    找1篇优秀代码贴图展示,并说明该代码功能是什么,优点是什么?
    代码可以是自己同学代码,也可以是其他地方找的代码。
    线性表合并运算函数:

    void mergeList(SeqList *LA, Seqlist *LB, Seqlist *LC)
    {
        int i,j,k;
        i=0; j=0; k=0;
        while(i <= LA->last || j <= LB->last)
        if(LA->elem[i] <= LB->elem[i] || (i <= LA->last && j > LB->last  ))
            {
                LC->elem[k] = LA->elem[i];
                i++; k++;
            }
    
        if(LA->elem[i] > LB->elem[j] || (i > LA->last && j <= LB->last))
            {
                LC->elem[k] = LB->elem[i];
                j++; k++; 
            }
    }
    

    功能:将两条顺序表中的元素合并并从小到大排列。
    优点:循环结束的条件是两条有序的线性表都走到空时才停止循环,虽然有可能出现下标越界的风险但是合理控制了这种情况,利用条件判断,当一条链表为空时,填入另一条链表的值,是程序大大简化。

  • 相关阅读:
    程序猿编程,软件设计都干什么?
    工作流——来龙去脉
    开发编码流程
    我的spring-boot开发环境
    JSR 303
    项目中java异常处理
    学习交流,一些数据结构和算法实现!
    C运算符
    js锚点
    玻璃工艺学笔记
  • 原文地址:https://www.cnblogs.com/doimpossible/p/8619681.html
Copyright © 2011-2022 走看看