| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 数据结构-带头双向循环链表 -> 正文阅读 |
|
[数据结构与算法]数据结构-带头双向循环链表 |
目录 链表的分类? ?链表的种类非常丰富,有带头结点的或不带头结点的,有单向的或双向的,有循环的或非循环的,这样组合起来有2*2*2=8种链表结构。 ? ?虽然有这么多的链表结构,但是我们实际中最常用的还是两种结构: ? ?最后我们再了解一下头结点与头指针的概念:不管带不带头结点,头指针都始终指向链表的第一个结点,而头结点是带头链表中第一个结点,该结点通常不存储数据。? ? ?引入头结点可以带来两个优点:1.由于第一个数据结点的位置被存储在头结点的指针域中,因此在链表的第一个位置上的操作和在链表其他位置上的操作一致,无须进行特殊处理。2.无论链表是否为空,其头指针都指向头结点,因此空表与非空表的处理也得到统一。 带头双向循环链表的概念及结构概念? ?链表是一种物理结构上非连续、非顺序的存储结构,数据元素的逻辑结构顺序是通过链表 ? ?而带头双向循环链表是链表组合中最复杂的结构。
结构? ?带头双向循环链表的结点需要存储前一个结点地址的指针prev,存储后一个结点地址的指针next以及存储数据的data,这样的带头双向循环链表的结点结构才算完整。 带头双向循环链表的基本操作初始化ListInit? ?带头双向循环链表的初始化操作本质上就是开辟一个头结点并将头指针指向开辟好的头结点。? ? 有两种实现方法:1.将头指针传给ListInit在函数体内把头指针的指向改为头结点,所以需要用到二级指针,传头指针的地址才能改变头指针的指向。2.直接将开辟好的头结点地址作为返回值来改变头指针的指向。 ? ?在这之前我们先实现一个开辟结点的函数,并将开辟好的结点中的prev和next指向自己。 尾插ListPushBack? ?尾插就是在链表的最后一个数据结点的后面增添一个新结点,本质上就是将最后一个数据结点的next指向newNode,而newNode的prev指向最后一个数据结点,因为是循环结构,还需将头结点的prev指向newNode,而newNode的next指向头结点。 ? ?与单链表相比,我们不需要遍历寻找最后一个数据结点,因为头结点的prev就是指向最后一个数据结点。 ? ?当链表为空时,其操作也是一样的: 头插ListPushFront? ?头插的操作就是将第一个数据结点的prev指向newNode,而newNode的next指向第一个数据结点,头结点的next指向newNode,而newNode的prev指向头结点。 ? ?当链表为空时,其操作也是一样的。 尾删ListPopBack? ?尾删的操作就是将最后一个数据结点的前一个结点的next指向头结点,而头结点的prev指向最后一个数据结点的前一个结点,然后释放掉最后一个数据结点。如果链表只剩下一个数据结点进行删除的话,操作也是一样的,尾删完最后一个结点就会回到头结点的next与prev指向自己的场景。 头删ListPopFront? ?头删的操作就是将第一个数据结点的下一个结点的prev指向头结点,而头结点的next指向第一个数据结点的下一个结点,然后释放掉第一个数据结点。如果链表只剩下一个数据结点进行删除的话,操作也是一样的,头删完最后一个结点就会回到头结点的next与prev指向自己的场景。 插入ListInsert? ?插入就是在pos位置前插入一个新结点,因为该链表为带头双向循环链表,所以我们可以直接找到pos位置的前一个结点,而不需要遍历找pos位置的前一个结点。具体操作就是将pos位置的前一个结点的next指向newNode,而newNode的prev指向pos位置的前一个结点,再将pos的prev指向newNode,而newNode的next指向pos即可完成插入操作。 ? ? 实现插入操作后,我们的尾插与头插可以复用插入操作: 删除ListErase? ?删除就是将pos位置的结点释放掉。具体操作就是将pos位置的前一个结点的next指向pos位置的后一个结点,而pos位置的后一个结点的prev指向pos位置的前一个结点,然后释放掉pos位置的结点。 ? ??实现删除操作后,我们的尾删与头删可以复用删除操作: 查找ListFind? ?按值查找就是将链表遍历一遍,并将查到存储该值的结点地址返回。 修改ListModify? ?修改操作就是将pos位置的data数据改为x数据。 ? ?将链表中所有存储2的结点改为存储0: 打印ListPrint? ?之前单链表遍历的结束条件是curr是否等于NULL,因为最后一个数据结点的next指向NULL。而带头双向循环链表的遍历结束条件是curr是否等于phead,因为最后一个数据结点的next指向phead。? 长度ListSize? ?求大小的操作同样是将链表遍历一遍,通过计数来求链表的长度。 ? ?另一种求链表长度的方法: 将头指针与一个整形size封装到一个结构体中,当链表增加数据时size++,若链表减少数据时size--这样就不需要遍历。 销毁ListDestroy? ?销毁的操作就是反复调用ListErase将所有的数据结点释放,最后将头结点也释放掉,调用ListDestroy之后记得将头指针置空。 动态顺序表与带头双向循环链表的比较? ?动态顺序表
? ?带头双向循环链表
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 23:47:48- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |