带头双向循环链表(数据结构初阶)

devtools/2025/1/17 11:07:30/

文章目录

  • 双向链表
    • 链表的分类
    • 概念与结构
    • 实现双向链表
      • 定义链表结构
      • 链表打印
      • 判空
      • 申请结点
      • 初始化
      • 头插尾插
      • 头删尾删
      • 查找
      • 指定位置插入和删除
      • 销毁链表
    • 顺序表和链表的分析
    • 结语

欢迎大家来到我的博客,给生活来点impetus!!
在这里插入图片描述
这一节我们学习双向链表数据结构初阶)

双向链表

链表的分类

在这里插入图片描述

概念与结构

在这里插入图片描述

注意:这⾥的“带头”跟前⾯我们说的“头结点”是两个概念,实际前⾯的在链表阶段称呼不严谨,但是为了同学们更好的理解就直接称为单链表的头结点。

带头链表⾥的头结点,实际为“哨兵位”,哨兵位结点不存储任何有效元素,只是站在这⾥“放哨的”。

链表存储的数据都是有效的,事实上,他是不存在头结点的

链表为空时是NULL
双向链表为空时此时表中仍然有哨兵位结点

链表为NULL,双向链表如下图:
在这里插入图片描述

实现双向链表

定义链表结构

双向链表既要能够存储数据,又要存储下一个和上一个结构体的地址
这样才能找到这个结构体。
在这里插入图片描述

链表打印

涉及链表打印,就一定涉及链表的遍历,双向链表的遍历与单链表存在区别
在这里插入图片描述
下面画图演示过程:
在这里插入图片描述

细节:1:判决条件 2:pcur的设立(phead的下一个结点)

判空

判空时在删除结点的时候十分有用。
可能你会问,和直接写while(pcur!=NULL)有区别吗
在这里插入图片描述

在该处的双向链表中为空,此时表中有头结点,不为NULL,判空就得改变
写为assert(!LTEmpty);
若写为while(pcur!=NULL),语句允许把双向链表把哨兵位删除,此时就不在是双向链表

申请结点

在这里插入图片描述

细节:malloc函数开辟是否成功,注意需要判断。

初始化

初始化具有两种思路:

1:先开辟结点,再来改变指针指向,不返回。
2:开辟结点改变指针指向一并完成,返回结点。

在这里插入图片描述

这里推荐使用第二种方法

头插尾插

尾插
在这里插入图片描述

需要先修改newnode,再修改原链表

头插
在这里插入图片描述

我们先修改newnode,再修改原链表

通过对比发现,为什么头插是在phead结点后面插入,而不是在phead结点之前插入?
因为在phead结点之前插入,就等价于尾插了

头删尾删

尾删
在这里插入图片描述

头删
在这里插入图片描述

头删和尾删断言的内容不在是判断空,而是判断是不是哨兵结点

前面我们已经说明,链表为空时为真,返回1,但是assert断言需要停止,就需要添加一个非(!)。不要被绕晕了。

查找

在这里插入图片描述

此处的查找为了给后面pos位置插入删除做铺垫,pos位置插入和删除就可以省去遍历的步骤了

指定位置插入和删除

在这里插入图片描述
pos之前插入数据与pos之后插入数据十分相同,如下:
在这里插入图片描述
指定位置删除数据。
在这里插入图片描述

销毁链表

在这里插入图片描述

此时我们发现,前方都是一级指针,销毁是二级指针,为了保证接口一致性,我们改为一级指针,,font color = red>函数调用完成后,手动free。

在这里插入图片描述

最后我们来总结一下细节:
1:双向链表为空时,只有一个哨兵位
2:双向链表进行操作时传递的一定为一级指针,因为哨兵位不能改变
3:注意分析对结点操作时受影响的节点或成员
4:插入结点时一定要先对newnode的指针进行操作
5:头插是在哨兵位后面插入
6:遍历时注意pcur的起始位置判决条件
7:销毁与删除的区别前者没有任何节点,后者一定有头结点
8:pos不可能为哨兵位,该结点存储数据无效
9:节点与数组不同的点:数组是连续的地址,结点的地址是不连续的

顺序表和链表的分析

在这里插入图片描述

当只用用来存储数据,不用任意位置插入删除,会使用顺序表
当需要频繁修改结点,任意位置插入或删除,使用链表

结语

感谢大家阅读我的博客,欢迎大家有新的知识点向我补充,也欢迎大家纠正我的错误,路漫漫其修远兮,吾将上下而求索,加油!!陌生人!!!在这里插入图片描述


http://www.ppmy.cn/devtools/151256.html

相关文章

root后如何隐藏环境?

很多小伙伴在给手机root之后以为就大功告成啦!其实你要做的才刚刚开始,很多安全性强的软件会侦查出你手机里的root,进而限制部分功能或直接拒绝你的访问。今天我来教大家一些常见的隐藏环境的方法以及步骤,希望对大家有帮助。 方…

做跨境电商服务器用什么宽带好?

做跨境电商服务器用什么宽带好?做跨境电商服务器,推荐选择光纤宽带或高性能的5G网络。光纤宽带高速稳定,适合处理大量数据和实时交互;5G网络则提供超高速移动连接,适合需要灵活性和移动性的卖家。具体选择需根据业务规…

Dual Split A2dp SBC Streams

背景 SBC是经典蓝牙A2DP强制支持的音频标准配置的codec,通常情况下,在我们的印象中SBC是蓝牙低质量音质的代名词,如果一个耳机或者音响只支持SBC一个codec,那么这个耳机或音响肯定是低端货,一般高端的人耳机都会支持一…

uniapp 小程序 textarea 层级穿透,聚焦光标位置错误怎么办?

前言 在开发微信小程序时,使用 textarea 组件可能会遇到一些棘手的问题。最近我在使用 uniapp 开发微信小程序时,就遇到了两个非常令人头疼的问题: 层级穿透:由于 textarea 是原生组件,任何元素都无法遮盖住它。当其…

【蓝桥杯】43687.赢球票

题目描述 某机构举办球票大奖赛。获奖选手有机会赢得若干张球票。 主持人拿出 N 张卡片(上面写着 1⋯N 的数字),打乱顺序,排成一个圆圈。 你可以从任意一张卡片开始顺时针数数: 1,2,3 ⋯ ⋯ 如果数到的数字刚好和卡片上的数字…

分类统计字符个数(PTA)C语言

本题要求实现一个函数,统计给定字符串中英文字母、空格或回车、数字字符和其他字符的个数。 函数接口定义: void StringCount( char s[] ); 其中 char s[] 是用户传入的字符串。函数StringCount须在一行内按照 letter 英文字母个数, blank 空格或回…

docker 与K8s的恩怨情仇

Docker 和 Kubernetes(通常简称为 K8s)是容器化和容器编排领域的两大重要工具,它们在技术生态中扮演着不同的角色,并且有着密切的关系。虽然有时候人们会讨论它们之间的关系,但实际上它们更多的是互补而不是对立。下面…

解析OVN架构及其在OpenStack中的集成

引言 随着云计算技术的发展,虚拟化网络成为云平台不可或缺的一部分。为了更好地管理和控制虚拟网络,Open Virtual Network (OVN) 应运而生。作为Open vSwitch (OVS) 的扩展,OVN 提供了对虚拟网络抽象的支持,使得大规模部署和管理…