本文章主要是供自己参考的错题订正,仅仅包含正确解答和错误写法以及反思。
6-1 单链表逆转
题目及要求可参考其他同学的博客
该代码摘抄自@沐辰墨染 ,侵歉删
PtrToNode Reverse(PtrToNode L)
{
PtrToNode p1=NULL,p2=NULL;
while(L!=NULL)
{
p2=L->Next;
L->Next=p1;
p1=L;
L=p2;
}
return p1;
}
过于简洁没有看懂,所以找到了解析单链表逆转简洁方法
对比自己写的,其实也是同样的思想,转变链表指向,不过加入了题目中要求的对空链表以及一个数值以及两个数值的链表逆转的判断,下面这个也是正确的。
List Reverse( List L )
{
if(L==NULL)//空链表
return NULL ;
else if(L->Next==NULL)//一个数值
return L;
else if(L->Next->Next==NULL){//两个数值
List tmp=L->Next;
L->Next->Next=L;
L->Next=NULL ;
return tmp;
}
else{
List pre=L;
List tmp=L->Next;
List nex=tmp->Next;
pre->Next=NULL;
while(nex!=NULL){
tmp->Next=pre;
pre=tmp,tmp=nex,nex=nex->Next;
}
tmp->Next=pre;
return tmp;
}
}
对比正确版本,一开始我犯了两个错误。
第一个是不知道空链表怎么表示,一直写的是L->Next==NULL.其实空链表的含义在这里可以理解为内存池没有空间分配给链表,因此L=malloc这一步的操作是不成功的因此只需要判断是否L=NULL即可。但是此时可能在初始化/定义L时需要将L直接赋予NULL,个人建议自己这么做。
第二个是两个数值时的交换,我一开始写的是交换数值但是一直过不了,至今不清楚原因,后来改成了交换链表节点.
int tmp;
tmp=L->Data;
L->Data=L->Next->Data;
L->Next->Data=tmp;
return L;
6-2 顺序链表的操作集
本题涉及顺序链表的 创建空链表 查找 插入 删除 四个操作.
我对顺序链表的理解错误时本题的根本性原因.
根本错误:链表的Last不是指MAXSIZE,而是当前操作状态下的元素最大下标
按照正确的理解,顺序链表相对于单链表来说,内存空间固定且连续,这起到了便于查找和限制内存的作用.但是在此之中插入和删除需要不断移动许多元素,即顺序链表的插入并不是按照数组下标插入的而是按照现有的元素个数和顺序并结合数组下标等一起安排.
我的错误之处在于想不通顺序链表到底是不是按照数组下标进行跳步排列,并且按照这种方法初始化空链表就变得很复杂.
其实它的插入单链表相似,断开插入口然后链接,不过顺序链表的连接体现为后边的元素整体后移,删除体现为后面的整体前移.
同时在本题中要考虑到空链表等特殊情况.
这个是别的同学的正确答案
我的典型错误函数
List MakeEmpty()
{
List L;
L=(List)malloc(sizeof(struct LNode));
for(int i=0;i<L->Last;i++)
L->Data[i]=EOF;
L->Last=MAXSIZE;
return L;
}
明显看出Last不理解,并且在顺序链表以及单链表中创建并初始化空链表不需要对储存数据单元进行操作.
其他函数错误过多.