游乐游手机版
首页/AI教程/文章详情

双向链表基本操作详解(附C语言完整代码)

时间:2026-06-24 12:04
掌握了双向链表的创建方法后,你可能会思考如何操作已建立的双向链表。例如,如何添加数据、删除节点、查找元素,或直接修改某个节点的值。本节将深入讲解双向链表的基本操作,涵盖添加、删除、查找与修改等核心功能。为便于讲解,我们继续使用上一节创建好的双向链表作为基础,其结构如图1所示:图1 双向链表结构示意图

掌握了双向链表的创建方法后,你可能会思考如何操作已建立的双向链表。例如,如何添加数据、删除节点、查找元素,或直接修改某个节点的值。本节将深入讲解双向链表的基本操作,涵盖添加、删除、查找与修改等核心功能。


为便于讲解,我们继续使用上一节创建好的双向链表作为基础,其结构如图1所示:

图1 双向链表结构示意图

双向链表添加节点

向双向链表添加数据时,根据插入位置的不同,通常可归纳为三种情况来处理。

1) 添加至表头

将新元素插入表头时,只需构建新节点与原表头之间的双向关系即可。假设新节点名为temp,原表头节点为head,两步操作即可完成:

temp->next=head; head->prior=temp;再将head指向temp,使其成为新的表头。


例如,将新元素7插入链表表头,具体过程如图2所示:

图2 向双向链表表头插入新元素

2) 添加至表的中间位置

与单链表插入类似,在双向链表中间位置插入节点需完成两个步骤,如图3所示:

新节点先与其直接后继节点建立双向关系;然后新节点的直接前驱再与其建立双向关系。

图3 向双向链表中间位置插入数据元素

3) 添加至表尾

表尾插入的逻辑与表头对称,步骤如下(如图4所示):

首先找到链表的最后一个节点;然后将新节点与最后一个节点建立双向链接。

图4 向双向链表尾部添加数据元素


综合以上三种情况,可编写双向链表添加数据的C语言代码。参考实现如下:

data = data;\n temp->prior = NULL;\n temp->next = NULL;\n //插入到链表头,要特殊考虑\n if (add == 1) {\n temp->next = head;\n head->prior = temp;\n head = temp;\n }\n else {\n int i;\n Line* body = head;\n //找到要插入位置的前一个结点\n for (i = 1; i < add - 1; i++) {\n body = body->next;\n //只要 body 不存在,表明插入位置输入错误\n if (!body) {\n printf(\"插入位置有误!\\n\");\n return head;\n }\n }\n //判断条件为真,说明插入位置为链表尾,实现第 2 种情况\n if (body && (body->next == NULL)) {\n body->next = temp;\n temp->prior = body;\n }\n else {\n //第 2 种情况的具体实现\n body->next->prior = temp;\n temp->next = body->next;\n body->next = temp;\n temp->prior = body;\n }\n }\n return head;\n}","heightLimit":true,"margin":true,"id":"Tk9BD"}">

双向链表删除节点

删除节点的思路与添加类似,同样分为三种情况。

1) 删除表头结点

删除表头节点的过程如图5所示:


图5 删除双向链表表头元素


具体步骤如下:

新建一个指针指向表头节点;断开表头节点与直接后继节点的关联,调整head指针指向,并将新表头的prior指针置为NULL;释放原表头节点占用的内存。

2) 删除表中结点

删除中间节点的过程如图6所示:


图6 删除双向链表中间节点

实现要点:

找到目标节点并用指针指向它;将目标节点从链表中摘除;释放该节点占用的内存。

3) 删除表尾结点

删除表尾节点的过程如图7所示:


图7 删除双向链表表尾节点


实现步骤:

找到表尾节点并用指针指向它;断开表尾节点与直接前驱的关联,将前驱节点的next指针置为NULL;释放表尾节点占用的内存。


双向链表删除节点的C语言实现代码如下:

data == data) {\n //删除表头结点\n if (temp->prior == NULL) {\n head = head->next;\n if (head) {\n head->prior = NULL;\n temp->next = NULL;\n }\n free(temp);\n return head;\n }\n //删除表中结点\n if (temp->prior && temp->next) {\n temp->next->prior = temp->prior;\n temp->prior->next = temp->next;\n free(temp);\n return head;\n }\n //删除表尾结点\n if (temp->next == NULL) {\n temp->prior->next = NULL;\n temp->prior = NULL;\n free(temp);\n return head;\n }\n }\n temp = temp->next;\n }\n printf(\"表中没有目标元素,删除失败\\n\");\n return head;\n}","heightLimit":true,"margin":true,"id":"FMNaj"}">

双向链表查找节点

通常情况下,双向链表与单链表一样,只维护一个头指针。因此查找指定元素的过程也与单链表类似:从头节点开始,依次遍历每个节点。


C语言实现代码如下:

data==elem) {\n return i;\n }\n i++;\n t=t->next;\n }\n //程序执行至此处,表示查找失败\n return -1;\n}","heightLimit":true,"margin":true,"id":"QpIp9"}">

双向链表更改节点

更改双向链表指定节点的数据域,本质上是先查找后修改。遍历链表找到目标节点后,直接更新其数据域即可。


实现此操作的C语言代码如下:

data == oldElem) {\n find = 1;\n break;\n }\n temp = temp->next;\n }\n //成功找到,则进行更改操作\n if (find == 1) {\n temp->data = newElem;\n return;\n }\n //查找失败,输出提示信息\n printf(\"链表中未找到目标元素,更改失败\\n\");\n}","heightLimit":true,"margin":true,"id":"U2DvC"}">

总结

以下是双向链表“增删查改”操作的完整C语言实现代码:

\n#include \ntypedef struct line {\n struct line* prior; //指向直接前趋\n int data;\n struct line* next; //指向直接后继\n}Line;\n\nLine* initLine(Line* head) {\n int i;\n Line* list = NULL;\n head = (Line*)malloc(sizeof(Line));//创建链表第一个结点(首元结点)\n head->prior = NULL;\n head->next = NULL;\n head->data = 1;\n list = head;\n for (i = 2; i <= 5; i++) {\n //创建并初始化一个新结点\n Line* body = (Line*)malloc(sizeof(Line));\n body->prior = NULL;\n body->next = NULL;\n body->data = i;\n //直接前趋结点的next指针指向新结点\n list->next = body;\n //新结点指向直接前趋结点\n body->prior = list;\n list = list->next;\n }\n return head;\n}\n\nvoid display(Line* head) {\n Line* temp = head;\n while (temp) {\n //如果该节点无后继节点,说明此节点是链表的最后一个节点\n if (temp->next == NULL) {\n printf(\"%d\\n\", temp->data);\n }\n else {\n printf(\"%d <-> \", temp->data);\n }\n temp = temp->next;\n }\n}\n\n//删除结点的函数,data为要删除结点的数据域的值\nLine* delLine(Line* head, int data) {\n Line* temp = head;\n while (temp) {\n if (temp->data == data) {\n //删除表头结点\n if (temp->prior == NULL) {\n head = head->next;\n if (head) {\n head->prior = NULL;\n temp->next = NULL;\n }\n free(temp);\n return head;\n }\n //删除表中结点\n if (temp->prior && temp->next) {\n temp->next->prior = temp->prior;\n temp->prior->next = temp->next;\n free(temp);\n return head;\n }\n //删除表尾结点\n if (temp->next == NULL) {\n temp->prior->next = NULL;\n temp->prior = NULL;\n free(temp);\n return head;\n }\n }\n temp = temp->next;\n }\n printf(\"表中没有目标元素,删除失败\\n\");\n return head;\n}\n\n//head为原双链表,elem表示被查找元素\nint selectElem(Line* head, int elem) {\n //新建一个指针t,初始化为头指针 head\n Line* t = head;\n int i = 1;\n while (t) {\n if (t->data == elem) {\n return i;\n }\n i++;\n t = t->next;\n }\n //程序执行至此处,表示查找失败\n return -1;\n}\n\n//更新函数,其中,add 表示要修改的元素,newElem 为新数据的值\nvoid amendElem(Line* p, int oldElem, int newElem) {\n Line* temp = p;\n int find = 0;\n //找到要修改的目标结点\n while (temp)\n {\n if (temp->data == oldElem) {\n find = 1;\n break;\n }\n temp = temp->next;\n }\n //成功找到,则进行更改操作\n if (find == 1) {\n temp->data = newElem;\n return;\n }\n //查找失败,输出提示信息\n printf(\"链表中未找到目标元素,更改失败\\n\");\n}\n//释放链表中结点占用的内存空间\nvoid free_line(Line* head) {\n Line* temp = head;\n while (temp) {\n head = head->next;\n free(temp);\n temp = head;\n }\n}\n\nint main()\n{\n //创建一个头指针\n Line* head = NULL;\n //调用链表创建函数\n head = initLine(head);\n printf(\"创建好的双向链表为:\\n\");\n display(head);\n\n printf(\"删除元素 2:\\n\");\n head = delLine(head, 2);\n display(head);\n\n printf(\"元素 3 的位置是:%d\\n\", selectElem(head, 3));\n \n printf(\"表中的元素 3 改为 6:\\n\");\n amendElem(head, 3, 6);\n display(head);\n\n free_line(head);\n return 0;\n}","heightLimit":true,"margin":true,"id":"9QeoO"}">

程序运行结果如下:

创建好的双向链表为:

1 <-> 2 <-> 3 <-> 4 <-> 5

删除元素 2:

1 <-> 3 <-> 4 <-> 5

元素 3 的位置是:2

表中的元素 3 改为 6:

1 <-> 6 <-> 4 <-> 5

来源:https://developer.aliyun.com/article/1742528
上一篇链路预测算法MATLAB代码实现与仿真 下一篇录音转文字神器排行榜实测推荐个人知识库搭建必备
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
CAD零基础入门教程:坐标输入、图层管理与基础绘图命令
AI教程 · 2026-09-01

CAD零基础入门教程:坐标输入、图层管理与基础绘图命令

本文面向CAD零基础学习者,系统讲解坐标输入、图层管理与基础绘图命令的核心用法。通过分步实操与常见问题排查,帮助新手建立精确绘图习惯,掌握规范出图的基础能力。

CAD从入门到项目交付:绘图、标注、图块与实战工作流
AI教程 · 2026-09-01

CAD从入门到项目交付:绘图、标注、图块与实战工作流

掌握CAD的核心在于建立“画得准、标得清、复用快、交付稳”的工作流。本文提供从环境设置、高频命令组合、标注规范、图块标准化到项目分阶段交付的完整路径,帮助初学者避免常见返工陷阱,独立完成可检查、可复用、可打印的工程图纸。

Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤
AI教程 · 2026-09-01

Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤

本文详细解析 Claude Code 登录前的账号类型区分方法,涵盖个人订阅、Teams 席位与企业 Enterprise 席位的授权路径差异。提供终端登录命令、环境变量排查及常见异常处理步骤,帮助用户快速完成正确授权并避免登录路径混淆。

Claude Code 文件修改前的权限模式配置与命令审批指南
AI教程 · 2026-09-01

Claude Code 文件修改前的权限模式配置与命令审批指南

本文详细介绍Claude Code在修改文件前的权限模式配置方法,包括defaultMode可选值、permissions allow与deny规则设置、多层级配置文件管理以及 status验证技巧,帮助开发者安全高效地使用AI编程助手。

Claude Code接入VS Code后先测扩展和终端命令
AI教程 · 2026-09-01

Claude Code接入VS Code后先测扩展和终端命令

在VS Code中接入Claude Code后,建议优先验证扩展面板与集成终端两条入口。本文提供标准检查顺序、关键命令与常见故障排查路径,帮助你快速确认环境就绪,避免后续开发受阻。