数据结构 之线性表
2020-03-16
23:52:12
小伙伴们又是新的一天!最近我在学数据结构与算法,这可一直是一个很头疼的坎,感觉学了他之后头要变秃了 。今天我复习到链表了,所以就熬夜给你们来说说链表的那些事。嘻嘻🤭。对于小白来说,链表的可是有点头疼,感觉他就如同小孩子一样,特别的皮,随便指向,有时候指着指着就蒙了。哈哈哈哈,我是不是说中了你们的心里呢?没事,没关系,现在我们就来探讨探讨链表的奥秘。🤭
线性表的概括
说到链表那咱们就来系统的说一下他吧。正所谓,线性表包括顺序结构和链式结构,顺序结构相对于来说比较简单可以看做成数组(数组记住了是从0开始的,所以数组的数要比正常的数要小:a[2]这是第三个元素。链式结构它包括{1:单链表 2:循环链表 3:双向链表};我先简单的说一下子链表和顺序表在概念的不同
下面我把顺序表和链表的各种方法说一下,进行一下对比。😁
一:单链表
1:插入
就好比实在原来的连个之间插入一个数
这个就是他插入的过程
经典部分是:s->next=p->next p->next=s(也就是头插法)
代码如下
1 /*****单链表插入*******/ 2 *声名一个结点p指向某一个结点初始化j从1开始 3 *当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1 4 *若到链表最后面p为空,说明第i个元素不存在 5 *否则查找成功,在系统生一个空节点s 6 *将数据元素e赋值给s->data 7 *单链表的插入标准语句p->next=s->next p->next=s 8 *返回成功 9 */ 10 Status ListInsert(LinkList *L ,ElenType *e) 11 { 12 int j; 13 LinkList p,s; 14 p=*L; 15 j=1; 16 while(j<i | | p )//寻找第一个结点 17 { 18 p=p->next; 19 ++j; 20 } 21 if(!p | |j>i ) 22 return ERROR; 23 s=(LinkList )malloc(sizeof(Node))//生成新的结点 24 s->data=*e;//把e赋值到这个数 25 s->next=p->next; 26 p->next=s; 27 return OK; 28 }
这个代码其实只要记住他的逻辑思维就OK了
为了防止大家和顺序表搞混 ,我再把顺序表的和这个对比一下子
1 /**********顺序表的插入************/ 2 *如果插入的位置不对,则出现异常 3 *如果线性表的长度大于数组的长度,则抛出异常或者动态增量容量 4 *从最后一个元素开始遍历到第i个位置,分别将他们往后移动一个位置 5 *将要插入的元素填入其中 6 *记住表长一定要加一*** 7 */ 8 status ListInsert(SeqList *L,ElenType *e) 9 { 10 int k; 11 if(L->length==MAXSIZE)//顺序表已满 12 return ERROR; 13 if(i<=L->length)//插入的数据不在表尾 14 { 15 for(k=L->length-1;k>i-;k++) 16 { 17 L->data[k+1]=L->data[k]; 18 } 19 } 20 L->data[i-1]=*e;//把e赋值给插入的那个元素,记住顺序表相当于数组,所以插回的第i个元素就相当于数组-1 21 L->lengrh++; 22 return OK; 23 }
2:删除
删除?顾名思义就是在原来的基础上删掉一个元素,但是,切记*****单链表这点和顺序表的删除不同,单链表时举个例子吧(就如同一家家三口,妈妈 爸爸 还有儿子 一起手牵手去逛街 但是呢 在大街上爸爸看到了一个美女,就多看了几眼,让妈妈知道啦,妈妈就撒开爸爸的手,牵起了儿子的手,这样就相当于把爸爸删除了,这是链表里可以这么形象的理解)而顺序表中的删除就是遍历元素,从后面一个一个的往前移动,那样就删掉了最后一个元素,以此类推哦🤭别忘记要把长度减。
1 /******单链表的删除******/ 2 *声名第一个结点p指向链表的第一个结点,初始化j从1开始 3 *当j<i时,就遍历链表,让p的指针向后移动不断指向下一个结点,j累加1 4 *若到链表末尾p为空,则说明第i个元素不存在; 5 *否则查找成功,将欲删除的结点p->next赋值给q 6 *单链表的删除标准语句时p->next=q->next; 7 *将q结点中的数据赋值给e,作为返回; 8 *释放q结点 9 *返回成功 10 */ 11 Status ListDelete(LinkList *L,int i,ElemType *e) 12 { 13 int j; 14 LinkList p,q; 15 p=*L; 16 j=1; 17 while(p->next && j<i ) 18 { 19 p=p->next; 20 ++j; 21 } 22 if(!(p->next) | | j>j ) 23 { 24 return ERROR; 25 } 26 q=p->next; 27 p->next=q->next;//将q的后继元素的值赋给p的后继 28 *e=q->data;//将q结点中的数据给e 29 free(q);//让系统回收次结点,释放内存 30 returnOK; 31 }
接着说说顺序表中的删除代码
1 /*********顺序表删除*******/ 2 *声明一个变量k 3 *判断是否在范围内 4 *拿数据存放到e中 5 *当元素在那个长度范围内 6 *进行循环,一直遍历后面的元素给前面的元素 7 *长度别忘记减一 8 *返回成功 9 */ 10 Status ListDelete(SeqList *L,int i,ElemType *e) 11 { 12 int k; 13 if(i<1 | | L->length ) 14 printf("该位置不在范围内“); 15 *e=L=>data[i-1]; 16 if(i<L->length) 17 { 18 for(k=i;k<L->length;k++) 19 { 20 L->data[k-1]=L->data[k]; 21 } 22 L->length--; 23 return OK; 24 }