1.本周学习总结
1.1思维导图
1.2.对线性表的认识及学习体会。
在顺序表,元素的插入和删除运算需要移动许多其他元素的位置,在链表中,要删除或插入元素只需修改链的关系即可,在有序表中进行操作可利用递增递减这一关系来查找位置等;
本章有些固定的插入删除的相关方法,怎样移动、怎样修改链的关系等,要对此相当熟悉才行。
在找链表的关系时,最好把图画出来,会有利于元素的操作。
2.PTA实验作业
2.1.题目1:顺序表删除重复元素
2.1.1设计思路
int i,j,m=0;//i,j用于对顺序表进行循环;m来控制循环次数,从而免去设置第三层循环来移动顺序表,同时记录删除个数。 for(i=0;i<L->length-m;i++) 外层从第一个数开始循环,之后依次移动 { for(j=i+1;j<=L->length-m;j++) 内层从第二个数开始循环,之后依次从外层循环的后一个数开始循环 { if(L->data[i]==L->data[j]) 出现相同数据 { L->data[j]=L->data[j+1]; 删除次数据,向后移动一位 m++; } } end for } end for L->length-=m; 顺序表长度减少
2.1.2代码截图
2.1.3本题PTA提交列表说明
- Q1:第一次设置循环时没考虑删除后的长度,内层循环过长,导致只能删除一个数据。
- A1:将内层循环从外层循环的后一个数开始循环,长度设置为length-m,控制循环次数。
- Q2:出现全部为重复数据时,删除过后会出现两个同样的数据,如输入5个1,删除后为1 1,测试点通不过。
- A2:测试后发现是最后一个数据未删除,考虑到内层循环要可以移动到最后一个数据时,修改循环条件后答案正确。
2.2.题目2:链表倒数第m个数
2.2.1设计思路
LNode *p=L; int i=0,j; 用i得出链表长度,j来将倒数改为正数第j个数 while(p->next!=NULL) { i++; p=p->next; } end while 正倒转换:j=i-m; if(j<m||m<=0) 不符合题意 return -1 else for(i=0;i<j;i++) { L移动 } end for return L->data
2.2.2代码截图
2.2.3本题PTA提交列表说明
Q1:刚开始用老师上课讲的同时移动两个指针p1,p2的方法来找,相隔m就是要找的数,但方法可能有错误,出现部分正确
A1:经过修改循环来保持p1,p2同时移动,但还是过不去测试点
Q2:修改方法,利用将倒数转化为正数的方法来做,没考虑不和题意时要返回-1,出现错误
A2:加上if条件来判断得到的j和输入的m是否合理,答案正确
2.3.题目3:有序链表合并
2.3.1设计思路
LinkList p,p1,p2; L1链第一个数p1=L1->next; L2链第一个数p2=L2->next; 重建p=L1; 不为空时while(p1!=NULL&&p2!=NULL) { 重建链表 if(p1中的数小) { p->next=p1; p1后移 } else { p->next=p2; p2后移 } end if while(p1或p2==p) 当有重复元素时 { p1,p2后移 } end while if(p2==NULL) p2短,提前为空时 { while(p1->data==p->data) { p1后移 p1=p1->next; } end while p->next=p1; } else p1提前为空时,将P2中不重复的加到P中 end if } end while
2.3.2代码截图
2.3.3本题PTA提交列表说明
Q1:在第一次设计时合并之后仍会出现相同数据,删除重复数据有错误,答案错误
A1:设计两个while循环比较p1(2)->data和p->data的大小,相同时移动链表
Q2:重建链时未加上较长链后边的元素,导致部分正确
A2:设计if语句判断哪条已经为空,再用循环来加上长链后边的元素
Q3:循环来加上长链后边的元素时出现错误
A3:得知加上链不必再用循环来加上,如P1较长,只需让p=p1即可加上后边的元素
3、阅读代码
3.1 题目:链式表操作集
本题要求实现链式表的操作集。实现链表中的寻找,插入,删除等操作
3.2 解题思路
- 首先建立链表:通过函数
List Insert( List L, ElementType X, Position P )
:将X插入在位置P指向的结点之前,返回链表的表头来建立链表。这题是不带头结点,直接建立指针 L = NULL;然后第一次连续插入插入X元素后(第一次连续插入其实就是在空链表的基础上创建单链表) 。所以第一次进行连续插入时,List Insert( List L, ElementType X, Position P )里面得L和P都是指向同一个位置的,要建立条件语句来区分第一次或不是第一次的插入。 设计函数查找X的位置:Position Find( List L, ElementType X )
:返回线性表中首次出现X的位置。用于后续的删除操作或判断次元素是否存在。主函数中,P = Find(L, X);而在Position Find();函数中返回的是要查找的元素对应的指针储存在了P中。设计函数删除p位置的元素:List Delete( List L, Position P )
:将位置P的元素删除并返回链表的表头。由于此题为不带头结点,代码在删除第一个元素和以后的元素是有区别的,需设计条件语句进行区分。
3.3 代码截图
3.4 学习体会
- 此题为不带头结点的操作集,在设计时必须区分第一次和后续操作,相比于带头结点更加复杂一些。
- 在进行插入建链表时,定义T链来指向L所指的位置,然后改变T的指向,让L保持位置不变。不带头结点如果改变了L的起始位置,后面的函数就找不到开头了,一定要不要随意改动头指针的位置。
- 好的算法就要节省空间,在进行删除操作时用一个指针P指向要被删除的第一个元素,然后将它free掉。
- 主函数中有L = Insert(L, X, NULL),即输入的要删除的最后一个元素需插在链表尾部,插入的时候我们就不符合第一次连续插入(L==P)的条件了,需要重新开始遍历,直接插在链表的最后一个位置。