双链表(常见的10个函数接口,配图详解每一个函数接口)(下)

简介: 双链表(常见的10个函数接口,配图详解每一个函数接口)(下)

8.修改:ListNodeModify


查找:ListNodeFind


对于修改和单链表一样需要先去查找,根据给出的数据返回的地址进行修改:


查找具体代码:

c1cd021e824741329f0912c593958c6e.png


修改具体代码:  

主函数里面的调用情况:  

c34b976450be42bda4190c10d9cf0904.png 

逻辑测试:  

我们不妨就把数据1修改为数据100:

ec2337db2b814c8d894e871e7257a97d.png

测试逻辑没问题


9.任意插入:ListNodeInsert


还记得对于单链表是怎样插入的吗?传了几个参数?当时我们传了3个参数:phead、pos、x;而对于双链表我们只需要传2个参数:pos、x;为什么呢?因为单链表传头结点是为了找到pos的前一个指针,我们只能通过遍历的方式;但是对于双链表我们pos->prev就直接找到上一个结点了!是不是更加的方便!!!


逻辑图:


dac7cc52712f4f3187db447f90e49703.png


image.png


我们首先要记住pos的前一个结点:prev = pos->prev,然后开始链接,prev->next = newnode,newnode->prev = prev,newnode->next = pos,pos->prev = newnode

具体代码:


image.png

逻辑测试:

在100前面插入1

d12a826516f44b0f89db7c95d3800617.png


逻辑测试没问题


10.任意删除:ListNodeErase


   对于删除我们只需要一个参数,就是pos的地址,然后还需要记录它的前一个位置prev和后一个位置next,最终释放pos,让pos置空。


逻辑图:

e8bc962669284ee9a207bad5d30d9fb6.png


根据上图进行链接,首先记住pos的前一个位置和后一个位置:prev = pos->prev,next = pos->next ;然后prev->next = next,next->prev = prev,free(pos),pos = NULL

具体代码:


0458269d075f414d807bc43fe0210e95.png


逻辑测试:

删除数据100进行打印测试


a573959820574ccc8cf5d39184705edd.png

逻辑测试没问题


11.计算大小:ListNodeSize


    对于计算大小很简单,我们定义一个计数器count就可以了;只需要注意一点,我们是从第二个数据开始计算数据的大小,对于头节点是不算的:


具体代码:

5de671586d4e484db89bbf3881df8c1b.png

逻辑测试:

统计此时数据的个数

75da088d5fbf447cbc7ab97249d6fbee.png


4个数据,计算的大小也是4,逻辑测试没问题


12.销毁:ListNodeDestory


链表的销毁和顺序表不同,顺序表是连续的空间,free一次就可以;而链表创建的空间是不连续的,我们malloc多少次,就需要free多少次;并且我们最终也要把头指针(哨兵位)也要释放掉;下面看具体代码:

具体代码:

d9432ed06ac54b29962a93aed1b0539b.png

13.代码复用:ListNodeInsert和ListNodeErase


对于双链表虽然结构复杂,但是操作起来很简单;包括一些特殊情况:在单链表中空链表和一个节点的问题,在这里一个代码段就可以适合所有的结果;是不是很方便呢?那么我们在思考一个问题,能否用任意插入和任意删除去替代其它函数呢?


1.任意位置插入代替尾插:任意位置插,是在pos的前面插入,我们思考一下,在头指针的前面插入,不就相当于在尾插了吗?


具体代码如下:

fbd4720a6a3749d498bf40022d5d2b0e.png



测试结果也能得到我们的预期结果:

9d4362b302ed4da4850838a474fa0b13.png

2.任意位置插入代替头插:

一直在头指针phead的next插入,不就相当于头插进行头插?

具体代码如下:

cc05222b8d2240e188f4b295d43c8916.png


测试结果也能得到我们的预期结果:

61c72e093b9d4e258d15c48409432fed.png

3.任意位置删除代替尾删

对于尾删,我们只需要传过去尾指针:phead->prev

具体代码如下:

45edfc480d354c138d211afa7f6f2e72.png


测试结果也能得到我们的预期结果:

52a9567a183248f3933cef0e151e9ee3.png

4.任意位置删除代替头删

对于尾删,我们只需要传过去尾指针:phead->next

具体代码如下:


159094cbea774d458b7a5c20f9dd64df.png

测试结果也能得到我们的预期结果:

fbe40a21ba96423c864a6aa713e8a3d9.png

14.所有具体代码:


8c15db7e326c448fb7ee3dd5f5e814e5.png

df904a207655490b83aeb1bc5f6891ed.png

总结:


还是那句话,对于链表的操作还是要动手画图!!!相对于单链表来说,双链表虽然结构复杂,但操作起来似乎更简单一点;无论是普通情况里面有很多元素,还是特殊情况空链表、一个节点的插入和删除;带头循环双链表都能用一段代码区解决;近乎完美。


这里我们大概写了10个常用的函数接口,希望对各位有所帮助;感兴趣的同学也可以写成项目工程的格式!!!


结束语


今天的分享就到这里,想要提升编程思维的,快快去注册牛客网开始刷题吧!各种大厂面试真题在等你哦!

💬刷题神器,从基础到大厂面试题👉点击跳转刷题网站


184068dc41e94efbb14e555f972eaa17.png

相关文章
|
5月前
|
算法
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
48 0
|
5月前
双向链表的创建、插入和删除、宏定义函数
双向链表的创建、插入和删除、宏定义函数
35 0
|
5月前
|
算法
数据结构和算法学习记录——线性表之双向链表(下)-头插函数、头删函数、查找函数、pos位置之前插入结点、pos位置删除结点及其复用、销毁链表函数
数据结构和算法学习记录——线性表之双向链表(下)-头插函数、头删函数、查找函数、pos位置之前插入结点、pos位置删除结点及其复用、销毁链表函数
29 0
|
5月前
|
算法
数据结构和算法学习记录——线性表之单链表(下)-头插函数、尾删函数、头删函数、查找函数、pos位置插入&删除数据、单链表销毁
数据结构和算法学习记录——线性表之单链表(下)-头插函数、尾删函数、头删函数、查找函数、pos位置插入&删除数据、单链表销毁
62 0
|
5月前
|
存储 算法
数据结构和算法学习记录——线性表之单链表(上)-初始单链表及其尾插函数(顺序表缺陷、单链表优点、链表打印)
数据结构和算法学习记录——线性表之单链表(上)-初始单链表及其尾插函数(顺序表缺陷、单链表优点、链表打印)
39 0
|
6月前
|
存储 缓存 C++
C++链表常用的函数编写(增查删改)内附完整程序
C++链表常用的函数编写(增查删改)内附完整程序
112 0
|
6月前
|
算法 Java C++
数据结构与算法面试题:实现一个函数,判断一个链表是否为回文链表。(提示:反转后半部分链表比对前半部分)
数据结构与算法面试题:实现一个函数,判断一个链表是否为回文链表。(提示:反转后半部分链表比对前半部分)
35 0
【数据结构】图文并茂,通过逻辑图带你轻松拿捏链表,实现各种接口功能(2)
【数据结构】图文并茂,通过逻辑图带你轻松拿捏链表,实现各种接口功能(2)
69 0
|
存储
【数据结构】图文并茂,通过逻辑图带你轻松拿捏链表,实现各种接口功能
【数据结构】图文并茂,通过逻辑图带你轻松拿捏链表,实现各种接口功能
141 0
|
存储
【双链表增删查改接口的实现】
【双链表增删查改接口的实现】
49 0