很多朋友看到,双向带头循环就会不由得虎躯一震,为之惊颤。
感觉好复杂啊,应该很不容易实现吧,其实,它是只纸老虎,善于伪装。所以我们不必担心。
我们要学习它,那就必须先去了解它。那怎么了解它呢,当然是从我们的概念入手啦!
1.概念
双向带头循环链表是一种链表数据结构,它由一系列节点组成,每个节点包含一个值(数据域)和两个指针,分别指向下一个节点和上一个节点。这种链表的特点是链表的头结点和尾结点都是同一个节点,并且头结点只存储一个指针,指向链表的第一个节点,而链表的最后一个节点的指针指向头结点。
2.相比于单链表,它又有什么优点呢
双向带头循环链表的优点是可以通过头结点快速访问链表中的任意一个节点,同时由于链表的循环结构,也方便进行遍历和查找操作。
双向带头循环链表的应用场景包括但不限于:
1. 实现动态内存分配和释放
2. 实现栈和队列等数据结构
3. 实现链表型数据库等
既然我们了解了它,我们不妨写一个吧
那我们老套路,先搞定结构体
然后就是我们要实现的函数接口了
如果兄弟们看了我上一篇博客就一定发现,我这里多了一个初始化函数,而且,在用一级指针接收参数,还没有返回值,这是为什么呢
这里就不跟大家卖关子了,还记得我们写的是什么链表吗,为什么上一篇要用二级指针去接收参数呢。在这里很多小伙伴应该都想明白了,我们写的是带头双向循环链表,那这个头怎么来的,难道创建结构体附赠的吗,显然不是。我们肯定要去自己创建头,所有我们应该先初始化链表。传二级指针又是什么原因呢,当然是为了改变传入的参数,也就是头结点。
到这大家应该都明白了吧
那我们接下来就一步一步的实现它吧。
有人会问了,为什么没有初始化data,因为本博主太懒了
既然我们有了头结点,那接下来
在这里有必要说一下,我们在每次malloc空间的时候,都应该去判断一下,是否成功。那么博主为什么没有判断呢,哈哈,当然是对自己电脑内存的自信喽,我能承认是太懒吗,哈哈,笑话我们既然写好了头插,和尾插,那我们不妨再写一个打印函数,存入数据打印出来,看我们写的是否真确
很好,没有出现任何问题
接下来,就是我们的头删和头删了
哈哈,有没有问题,我们有了头插,尾插,头删,尾删。那我们想着任意位置插入,删除,又当如何。我知道你们很急,但你先别急。接下来,看我操作!
知道你们很急,那我们直接测试
很多朋友可能想到了,我们既然有了任意位置的插入和删除,那我们能不能把尾插和头插,尾删和头删利用任意位置的插入,删除搞定呢
很有眼力见嘛,小伙子,那就交给你们喽
骗你们的啦,
很好,我们现在就差最后一步,
喂喂喂,起床啦,悄悄的说(吃饭啦)
既然大家都休息好了,那我们就把最后一步销毁链表不补上吧
既然看完了,那你还不