【数据结构-C】双向循环链表基本操作及图解分析

【数据结构-C】双向循环链表基本操作及图解分析目录 双向链表介绍 双向链表的基本操作及图解分析 1 双向链表创建新的结点 2 双向链表初始化 3 双向链表的尾插 4 双向链表的头插 5 双向链表的头删 6 双向链表的尾删 7 查找某个结点并返回该节点地址 8 在某结点前插入一个新的结点 9 删除某个结点 10 销毁双向链表总结 双向链表介绍双向链表的结点 指针域 1 数据域 指针域 2 指针域 1 指向该结点

目录

?双向链表介绍

?双向链表的基本操作及图解分析

?1.双向链表创建新的结点

?2.双向链表初始化

?3.双向链表的尾插

?4.双向链表的头插

?5.双向链表的头删

?6.双向链表的尾删

?7.查找某个结点并返回该节点地址

?8.在某结点前插入一个新的结点

?9.删除某个结点

?10.销毁双向链表

总结


?双向链表介绍

双向链表的结点:指针域1+数据域+指针域2

?指针域1:指向该结点前面一个结点

?指针域2:指向该结点后面一个结点

【数据结构-C】双向循环链表基本操作及图解分析

结构体表示结点:

typedef struct DulNode { struct DulNode *prev; struct DulNode *next; ElemType data; }DulNode; 

带头循环双向链表的头结点当链表为空时,头结点的指针域1指向自身,头结点的指针域2指向自身。

注意?:头结点的数据域不储存数据,在初始化时可以随机给一个数,但是这个数不具有任何作用。

【数据结构-C】双向循环链表基本操作及图解分析

【数据结构-C】双向循环链表基本操作及图解分析

 ➖一条简单的带头双向循环链表

⚙物理结构:

【数据结构-C】双向循环链表基本操作及图解分析

⚙逻辑结构:

【数据结构-C】双向循环链表基本操作及图解分析

?双向链表的基本操作及图解分析

?1.双向链表创建新的结点

DulNode* BuyNewNode(ElemType data) { DulNode* newNode = (DulNode*)malloc(sizeof(DulNode)); //结点初始化 newNode->data = data; newNode->prev = NULL; newNode->next = NULL; return newNode; }

?2.双向链表初始化

初始化:创建一个头结点,使得头结点的指针域指向自己,并返回头结点的地址。

DulNode* InitList() { DulNode* newNode = BuyNewNode(0); //让该结点的指针域指向自己,作为头结点 newNode->next = newNode; newNode->prev = newNode; return newNode; }

?3.双向链表的尾插

【数据结构-C】双向循环链表基本操作及图解分析

?Step1:创建新结点,找到尾结点并保存

?Step2:将尾结点与新结点连接

【数据结构-C】双向循环链表基本操作及图解分析

?Step3:将头结点与新结点连接

【数据结构-C】双向循环链表基本操作及图解分析

void ListPushBack(DulNode* phead, ElemType data) { assert(phead); DulNode* newNode = BuyNewNode(data);//创建新结点 DulNode* tail = phead->prev;//找到尾结点 //尾结点与新结点连接 tail->next = newNode; newNode->prev = tail; //头结点与新结点连接 newNode->next = phead; phead->prev = newNode; }

?4.双向链表的头插

【数据结构-C】双向循环链表基本操作及图解分析

?Step1:找到第一个结点。

?Step2:将第一个结点与新结点连接。

【数据结构-C】双向循环链表基本操作及图解分析

?Step3:将新结点与头结点连接

【数据结构-C】双向循环链表基本操作及图解分析

void ListPushFront(DulNode* phead, ElemType data) { assert(phead); DulNode* newNode = BuyNewNode(data); DulNode* first = phead->next;//找到第一个结点 //新结点与第一个结点连接 first->prev = newNode; newNode->next = first; //新结点与头结点连接 newNode->prev = phead; phead->next = newNode; }

?5.双向链表的头删

?Step1:找到第一个结点和第二个结点

【数据结构-C】双向循环链表基本操作及图解分析

?Step2:将第二个结点与头结点连接

【数据结构-C】双向循环链表基本操作及图解分析

?Step3:释放第一个结点

注意?:当链表为空时,使用该操作会将链表销毁,所以当链表为空时使用assert()打印错误信息。

void ListPopFront(DulNode* phead) { assert(phead); assert(phead->next != phead);//当链表为空时 DulNode* first = phead->next;//记录第一个结点 DulNode* second = first->next;//记录第二个结点 //将头结点与第二个结点连接 second->prev=phead; phead->next=second; //释放第一个结点 free(first); first = NULL; }

?6.双向链表的尾删

?Step1:找到最后一个结点和倒数第二个结点

【数据结构-C】双向循环链表基本操作及图解分析

?Step2:将倒数第二个结点与头结点连接

【数据结构-C】双向循环链表基本操作及图解分析

 ?Step2:将最后一个结点释放

注意?:当链表为空时,使用该操作会将链表销毁,所以当链表为空时使用assert()打印错误信息。

void ListPopBack(DulNode* phead) { assert(phead); assert(phead->next != phead); DulNode* end = phead->prev;//记录尾结点 DulNode* prev = end->prev;//记录倒数第二个结点 //将头结点与倒数第二个结点 prev->next = phead;//尾结点的前一个结点后继尾头结点 phead->prev = prev;//头结点的前驱为尾结点的前一个结点 free(end); end = NULL; }

?7.查找某个结点并返回该节点地址

DulNode* ListFind(DulNode* phead, ElemType data) { DulNode* cur = phead->next;//定义一个遍历链表的指针 while (cur !=phead) { if (cur->data == data) { return cur; } cur = cur->next; } return NULL; }

?8.在某结点前插入一个新的结点

?Step1:找到某结点的前一个结点

【数据结构-C】双向循环链表基本操作及图解分析

?Step2:将新结点与某结点连接

【数据结构-C】双向循环链表基本操作及图解分析

?Step3:将新结点与某结点的前一个结点连接

【数据结构-C】双向循环链表基本操作及图解分析

void ListInsert(DulNode* pos, ElemType data) { assert(pos); DulNode* newNode = BuyNewNode(data); DulNode* prev = pos->prev;//记录插入位置的前一个结点 //新结点和pos结点连接 newNode->next = pos; pos->prev = newNode; //pos前一个结点和新结点连接 newNode->prev = prev; prev->next = newNode; }

?9.删除某个结点

?Step1:找到某结点的前一个结点和后一个结点

【数据结构-C】双向循环链表基本操作及图解分析

?Step2:将前一个结点和后一个结点连接

【数据结构-C】双向循环链表基本操作及图解分析

 ?Step3:释放删除结点

void ListEarst(DulNode* pos) { assert(pos); DulNode* prev = pos->prev; DulNode* next = pos->next; //将删除结点的前后结点进行连接 prev->next = next; next->prev = prev; free(pos); pos = NULL; }

?10.销毁双向链表

void ListErase(DulNode *phead) { DulNode *cur=phead->next; while(cur != phead) { DulNode *next=cur->next;//先找到下一个结点 free(cur);//释放该结点 cur=next; } }

总结

链表包括八种

?:单向带头循环链表

?:单向带头非循环链表

?:单向不带头循环链表

?:单向不带头非循环链表

?:双向带头循环链表

?:双向带头非循环链表

?:双向不带头循环链表

?:双向不带头非循环链表

?单向不带头非循环链表 一般不会单独用来存数据。实际中更多是作为其他数据结 构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多

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

能力有限,有错误之处还请能够指出。谢谢大家的观看。

最后祝大家:岁岁平安,虎虎生威。

【数据结构-C】双向循环链表基本操作及图解分析

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222658.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午3:16
下一篇 2026年3月17日 下午3:16


相关推荐

  • openstack介绍_openstack开发

    openstack介绍_openstack开发什么是云计算最早提出来是亚马逊公司,发家是靠卖书,最后自己把自己卖书的业务移到互联网上,随着自己公司业务的增加,自己公司内部服务器就不够用了,慢慢就开始做虚拟化,做了虚拟化之后,随着公司组织架构的复

    2022年8月2日
    8
  • 细说php精要版 百度云,细说php精要版

    细说php精要版 百度云,细说php精要版内容简介 细说 PHP 开发 Web 应用程序 PHP 是最理想的工具 易于使用 功能强大 成本低廉 高安全性 开发速度快且执行灵活 细说 PHP 以实用为目标设计 包含 PHP 开发最主流的各项技术 对每一个知识点都进行了深入详细的讲解 并附有大量的实例代码 图文并茂 系统地介绍了 PHP 的相关技术及其在实际 Web 开发中的应用 细说 PHP 共 17 章 每一章都是 PHP 独立知识点的总结

    2026年3月19日
    2
  • 如何求有向图的拓补序列

    如何求有向图的拓补序列求一个有向图的拓扑序列也是图论的基本题型 但是一般不会显式的看出题意是求拓扑序列或者求是否存在拓扑序列 拓扑序列一般用来判断一个图是否是一个有向无环图 如果一个图存在符合拓扑次序的序列则该图是有向无环图 反之则不是 求拓扑序列步骤 nbsp nbsp 1 找到一个入度为 0 的点作为拓扑序列的第一个点 nbsp nbsp 2 把该点和该点所有的边从图中删去 nbsp nbsp 3 再在新的图中选择一个入度为 0 的点作为拓扑系列

    2026年3月19日
    2
  • mybatis逆向生成java代码_mybatis生成

    mybatis逆向生成java代码_mybatis生成前言有时候,我们创建实体类需要跟数据库表里面的字段对应起来。假如一张表有数百个字段,那么手动去写实体类的话就比较麻烦,而且容易出错。解决方案其实解决这个问题的方式有很多,本文介绍其中一种解决方案,通过mybatis的逆向工程生成实体类。本文使用的数据库是Oracle,MySQL只需要修改jar包以及generator.properties配置即可。可以从公众号【程序员高手之路】回复“逆向工程”获取源码!Step1修改p…

    2022年8月21日
    8
  • css cursor 属性有哪些常见用法_鼠标样式属性讲解

    css cursor 属性有哪些常见用法_鼠标样式属性讲解

    2026年3月16日
    2
  • Hunyuan-MT Pro新手教程:中文→英语技术文档翻译的Temperature调优策略

    Hunyuan-MT Pro新手教程:中文→英语技术文档翻译的Temperature调优策略

    2026年3月13日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号