数据结构入门 — 链表详解_双向链表

简介: 数据结构入门 — 双向链表详解双向链表(Doubly Linked List)是一种链表数据结构,它的每个节点都含有两个指针,一个指向前一个节点,一个指向后一个节点。相比较于单向链表,双向链表可以双向遍历,即可以从头到尾或从尾到头遍历链表。在双向链表中,每个节点包含两个指针域和一个数据域。其中,一个指针指向前驱节点,另一个指针指向后继节点。

前言

数据结构入门 — 双向链表详解

关注博主,后期持续更新系列文章

*****感谢观看,希望对你有所帮助*****


系列文章

第一篇:数据结构入门 — 链表详解_单链表

第二篇:数据结构入门 — 链表详解_双向链表

第三篇:数据结构入门 — 链表详解_循环链表


文章目录

前言

系列文章

什么是双向链表

概念与结构(图文)

双向链表与单链表的区别

带头双向循环链表接口实现(代码演示)

1. 动态存储结构

2.双向链表打印

3.增删查改接口

4.双向链表销毁

五、所有文件代码

1. Gitee链接

总结


什么是双向链表

双向链表(Doubly Linked List)是一种链表数据结构,它的每个节点都含有两个指针,一个指向前一个节点,一个指向后一个节点。相比较于单向链表,双向链表可以双向遍历,即可以从头到尾或从尾到头遍历链表。在双向链表中,每个节点包含两个指针域和一个数据域。其中,一个指针指向前驱节点,另一个指针指向后继节点。这两个指针使得双向链表的插入、删除等操作不需要像单向链表那样需要遍历整个链表来寻找前驱节点,提高了链表的操作效率。


概念与结构(图文)

image.png

带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。


双向链表与单链表的区别

双向链表和单链表是两种不同的链表结构。


单向链表是一种链表,在每个节点中包含指向下一个节点的指针。这意味着在单向链表中,节点只能从头开始遍历到尾部。在单向链表中,每个节点只存储指向下一个节点的指针,而不存储指向前一个节点的指针。


双向链表是一种链表,在每个节点中包含指向下一个节点和前一个节点的指针。这意味着在双向链表中,节点可以被从头到尾或从尾到头遍历。在双向链表中,每个节点存储指向前一个节点和下一个节点的指针。


因此,双向链表可以更方便地进行双向遍历,但是需要更多的内存空间来存储每个节点的两个指针。相比之下,在单向链表中,只需要一个指针来指向下一个节点,因此内存占用量更小。


带头双向循环链表接口实现(代码演示)

带头+双向+循环链表增删查改实现


1. 动态存储结构

typedefintSTDataType;
typedefstructListNode{
structListNode*prev;
structListNode*next;
STDataTypedata;
}LTNode;

双向链表打印

voidLTPrint(LTNode*phead)
{
assert(phead);
printf("phead<->");
//跳过哨兵位LTNode*cur=phead->next;
while (cur!=phead)
    {
printf("%d<->", cur->data);
cur=cur->next;
    }
printf("\n");
}

增删查改接口

根据增删查改顺序编排


双向链表头插:

//头插voidLTPushFront(LTNode*phead, STDataTypex)
{
assert(phead);
LTNode*newnode=BuyLTNode(x);
LTNode*first=phead->next;
newnode->next=first;
first->prev=newnode;
phead->next=newnode;
newnode->prev=phead;
}

双向链表尾插:

//尾插voidLTPushBack(LTNode*phead, STDataTypex)
{
assert(phead);
LTNode*newnode=BuyLTNode(x);
//找到最后一个LTNode*tail=phead->prev;
newnode->prev=tail;
tail->next=newnode;
newnode->next=phead;
phead->prev=newnode;
}

双向链表头删:

//头删voidLTPopFront(LTNode*phead)
{
assert(phead);
assert(phead->next!=phead);
LTNode*first=phead->next;
LTNode*second=first->next;
free(first);
phead->next=second;
second->prev=phead;
}

双向链表尾删:

//尾删voidLTPopBack(LTNode*phead)
{
assert(phead);
assert(phead->next!=phead);
LTNode*tail=phead->prev;
LTNode*tailprev=tail->prev;
free(tail);
phead->prev=tailprev;
tailprev->next=phead;
}

查找:

LTNode*LTFind(LTNode*phead, STDataTypex)
{
assert(phead);
LTNode*cur=phead->next;
while (cur!=phead)
    {
if (cur->data==x)
        {
returncur;
        }
cur=cur->next;
    }
returnNULL;
}

在指点位置插入:

voidLTInsert(LTNode*pos, STDataTypex)
{
LTNode*newnode=BuyLTNode(x);
LTNode*posprev=pos->prev;
newnode->next=pos;
pos->prev=newnode;
posprev->next=newnode;
newnode->prev=posprev;
}

在指点位置删除:

// 把pos删除voidLTErase(LTNode*pos)
{
LTNode*posprev=pos->prev;
LTNode*posnext=pos->next;
free(pos);
posprev->next=posnext;
posnext->prev=posprev;
}

双向链表销毁

voidLTDestory(LTNode*phead)
{
LTNode*cur=phead->next;
while (cur!=phead)
    {
LTNode*next=cur->next;
free(cur);
cur=next;
    }
free(phead);
phead=NULL;
}

五、所有文件代码


1. Gitee链接

***查看所有代码***

点击右边蓝色文字 DuckBro Gitee 代码仓库


总结

带头双向循环链表的基本概念和常见操作。带头双向循环链表是一种特殊的双向链表,它多了一个头节点和一个尾节点,并且首尾相连形成一个环。


这样可以实现循环遍历链表。在带头双向循环链表中,插入、删除节点等操作都有特殊处理方式。带头双向循环链表在实际应用中比较常见,如操作系统中的进程管理、音乐播放器中的播放列表等。


如这篇博客对大家有帮助的话,希望 三连 支持一下 !!! 如果有错误感谢大佬的斧正 如有 其他见解发到评论区,一起学习 一起进步。


目录
相关文章
|
2月前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
63 4
|
8天前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
68 5
|
2月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
114 4
|
2月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
2月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
53 0
|
2月前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
78 0
|
2月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
230 9
|
2月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
37 1
|
2月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。

热门文章

最新文章