链表的分类:
链表可按照:1.双向,单向。2.循环,不循环。3.带头,不带头。
根据不同组合可分为8类。其中不带头单项不循环链表为单链表。
单链表的第一个节点为头节点:
节点的创建:
通过这样一个函数我们可以实现创建链表的每一个结点。
其中每一个节点都是一个结构体,有两个变量,一个变量为值,另一个变量为指向下一个节点的指针。如果没有下一个节点则指向空节点(NULL)。
上图SLTDataType是我们使用typedef取名的变量类型,原名为int。
链表的输出:
将头节点的指针传给函数,当当前节点不为空时,输出当前节点的值并指向下一个节点。
链表的尾插:
注意:我们传入的是头节点的指针,目的是可以改变存储头节点地址的指针
首先使用assert防止传入的指针为空指针。
然后创建一个新的节点。
1.
如果一开始就没有元素,那么就将新产生的节点作为头节点。
2.
如果一开始有元素,那么就要一直往下找(注意:'*'的优先级比'->'高,所以要套括号)。当找到的节点的下一个节点为空,则证明该节点为链表的最后一个元素,将新节点插在该节点的后方即可,
头插:
与尾插同样的原理,如果没有元素则将头节点指向新节点。
如果有元素,那么则将新元素放在头节点的下一个节点即可。新节点指向头节点的下一个位置,头节点指向新节点即可。(顺序不能调换,否则就找不到原来的元素了)
尾删:
还是要先报警告,传进去的不能为空指针。
1.如果原链表只有一个元素,那么就free掉头节点,将头节点指向NULL。
2.如果不止一个元素,则一直往后找。直到某一个元素他的下一个节点的下一个节点为空。
如果只是找到某个节点他的下一个节点为空那么就没有办法实现将倒数第二个元素的下一个节点指向空。
头删:
与尾删类似的原理。但是会方便很多,只要让头节点指向第二个节点即可。
查找元素:
就单纯的往后找,如果某个节点的值为指定的值就返回地址,否则返回空。
但是缺点是只能找到第一个指定元素的地址。
在指定位置之前插入元素:
如果是是头节点那么进行头插,如果不是则找到那一个节点的前一个节点,前一个节点指向新节点,新节点指向指定位置即可。
删除指定位置节点:
同样的原理,头节点头删,非头节点则找到对应位置的前一个位置,使他指向对应位置的后一个位置,释放掉对应位置即可。
在指定位置之后插入数据:
找到对应节点,对应节点指向新节点,新节点指向对应节点的下一个位置(非头尾节点需要改前后位置),尾节点则指向新节点即可。
删除pos之后的节点:
都是类似的。因为是删除之后的位置,所以修改的是pos节点和pos后两个节点的位置。因此特殊的位置只有尾节点的前一个结点和尾节点,只需要修改一个值(尾节点free(NULL),非尾节点释放尾节点)。
销毁链表:
从前往后删即可,多一个指针存储当前位置,当前位置指针指向后一位,释放掉新增的指针即可。
解释:最后的情况是,a指向尾节点,mn指向尾节点的后一个位置即NULL,释放尾节点,mn为空退出循环)
释放完全部元素之后将需要将记录头节点的指针置空,因此传递的是二级指针。
总结:需要可能修改记录头节点的指针则传递二级指针,不需要则只需传递一级,仅修改结构体的值即可。