双向链表的创建与修改

在上一篇文章中我们介绍了单链表的创建与修改。

这次,我们将在单链表的基础上介绍双链表。

单链表为不带头单向不循环链表。

而双链表则为带头双向循环链表,与单链表完全相反。

双向链表的介绍

对比:

指向:单链表只能指向下一个节点。而双向链表既指向下一个,又指向前一个节点。

循环:单链表的最后一个节点指向NULL。而双向链表最后又指向了头节点。

带头:之前我们说的不太严谨,头节点和带头结点是两种东西,可以将带头结点head理解为“哨兵位”,即只负责监督,不参与链表修改。

单链表的头节点指的是第一个有效节点,而双向链表的带头结点则是单独一块参与进去的节点,他的下一个节点为第一个有效节点。

双向链表实现:

双向链表也是一个结构体,比单链表多了个前一个prev。

初始化:

单链表的初始化即创建一个“哨兵位”,“哨兵位”的值我们给一个-1用来做标记,哨兵位的值只要是链表有效值中不可能取到的极端值即可,只要能证明这是哨兵位即可。

哨兵位的前一位和后一位都指向自己(切记,双向链表不能指向空)

创建新节点:

单纯可以省一点字。

双向链表的销毁:

同样是对传入的参数报警告。由于双向链表中哨兵位始终存在不会被删除,所以我们传递哨兵位时只需要传递一级指针即可。

这里可能会有点乱。

我们先将最后一个节点的next指向空。由于双向链表有前一位的概念,因此哨兵位的前一位就是最后一位。

然后创建一个变量mn用来存储第一个哨兵位后第一个节点的位置。

如果mn为空,说明最后一位也是哨兵位,将哨兵位释放掉返回即可。

如果mn不为空,那么直接释放掉哨兵位,进入循环:

若mn的下一位不为空,那么则将mn指向后一位,通过prve则可以实现释放空间。

最后出循环的时候说明mn的后一位为空。但是后一位为空的只有上方经过修改的最后一位,所以将mn释放掉即可。

输出链表:

哨兵位后一位为第一个有效节点,当当前节点不为哨兵位时输出即可,依次后移。

判断链表是否为空:

很简单,哨兵位的后一位还是哨兵位那么链表就是空的,这个会在后面用到。

尾插:

从这里开始,双向链表和单向链表的区别逐渐显现出来。

创建新节点,新节点前一位指向哨兵位前一位,后一位指向哨兵位。哨兵位前一位(即尾节点)的后一位修改为新节点,哨兵位的前一位修改为新节点即可。(尾节点和哨兵位的修改不能调换顺序)。

尾删:

同样的,如果只有哨兵位则不执行(LTEmpty在这里发挥作用)。

尾节点可以很轻松的找到,和尾插同样的原理即可。

头插:

同上。

头删:

同上。

在固定位置后插入

直接插入即可,只需修改固定位置的后一位朝向和该位置后一位的前一位朝向即可。

删除某一结点:

修改前后两指针朝向,删除该数据。

找节点:

这个与单链表是同样的原理,只能往后挪一位一位找。

展示:

总结:

链表和数组最大的区别在于:

数组可以很方便的找到某一位上的值,但是链表只能不停往后找。

链表可以很方便的移除某个值,但是数组只能一位一位交换位置。

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值