双链表详解(初始化、插入、删除、遍历)(数据结构与算法)

1. 单链表与双链表的区别

单链表(Singly Linked List)和双链表(Doubly Linked List)是两种常见的链表数据结构,它们在节点之间的连接方式上有所区别。

单链表:

  1. 单链表的每个节点包含两个部分:数据域和指针域。
  2. 数据域存储节点的值或数据。
  3. 指针域存储指向下一个节点的指针,即单链表的指针指向下一个节点。
  4. 单链表只能从头节点开始顺序访问,通过指针域进行节点之间的连接。
  5. 单链表只能单向遍历,即只能从头节点开始,沿着指针域逐个访问下一个节点。
  6. 无法逆向检索,有时候不太方便

双链表:
7. 双链表的每个节点包含三个部分:数据域、指向前一个节点的指针和指向下一个节点的指针。
8. 数据域存储节点的值或数据。
9. 前驱指针指向前一个节点,后继指针指向下一个节点。
10. 双链表可以双向遍历,既能从头节点顺序遍历,也可以从尾节点逆序遍历。
11. 双链表相较于单链表需要额外存储指向前一个节点的指针,因此会在空间上占用更多的内存。
12. 可进可退,存储密度更低一点

单链表和双链表的选择取决于需要解决的问题和应用场景。对于只需要顺序遍历或仅从头部开始操作的情况,单链表可能是更简洁和高效的选择。但对于需要在两个方向上遍历或在任意位置插入或删除节点的情况,双链表就更有优势了。

双链表: 初始化、插入、删除、遍历


2. 双链表的初始化(带头结点)

//初始化双链表 
typedef struct DNode		//定义双链表结点类型
{Elemtype data;			//数据域struct DNode *prior, *next;  //前驱和后继指针
}DNode, *DLinkList;	bool InitDLinkList(DLinkList &L)
{L = (DNode *) malloc(sizeof(DNode));		//分配一个头结点if(L == NULL)		//内存不足,分配失败return false;L->prior = NULL;		//头结点的prior永远指向NULLL->next = NULL;			//头结点之后暂时还没有结点return true;	
}
void testDLinkList()
{DLinkList L; //初始化双链表InitDLinkList(L);//后续代码......
}//判断双链表是否为空(带头结点)
bool Empty(DLinkList L) 
{	if(L->next == NULL)return true;elsereturn false;
}

3. 双链表的插入

在双链表中插入节点需要更新前驱节点和后继节点的指针连接,操作相对比较复杂。

  1. 首先,创建一个新节点,并设置它的数据值。
  2. 找到要插入位置的前驱节点。
  3. 将新节点的前驱指针指向前驱节点。
  4. 将新节点的后继指针指向前驱节点的后继节点。
  5. 更新前驱节点的后继指针指向新节点。
  6. 如果新节点的后继节点非空,将后继节点的前驱指针指向新节点。
  • 若结点在双链表插入数据元素e,且p结点有后继结点,如下图所示。
    在这里插入图片描述
    程序设计如下:
//在p结点之后插入s结点
bool InsertNextDNode(DNode *P, DNode *s)
{s->next = p->next;	//将结点*s插入到结点*p之后, 如上图步骤1p->next->prior = s;  //如上图步骤2s->prior = p;     //如上图步骤3p->next = s;      //如上图步骤4
}

在这里插入图片描述

  • 如果p是最后一个结点,会发生什么?

p->next->prior = s; //如上图步骤2 这一行代码将出现问题 p->next指向的是NULL, 改进如下:

在这里插入图片描述
程序设计如下:注意修改指针时要注意顺序!!!

//在p结点之后插入s结点
bool InsertNextDNode(DNode *p, DNode *s)
{if (p == NULL || s == NULL) //非法参数return false;s->next = p->next;        //  (*)if(p->next != NULL){p->next->prior = s;  //如果p结点有后继结点,就回到了上一个情况}s->prior = p;	  //蓝色箭头操作p->next = s;      //橙色箭头操作    (**)    return true;  //插入成功
}
  • 指针顺序不能错! 假如 (*) 与(**)行交换。 那么就会出现如下图情况,p指针next与s->next指向同一位置。
    在这里插入图片描述
    用后插操作实现结点插入有什么好处?
  • 按位序插入前插操作:效果等同于 ====> 可以先找到前驱结点,再对其做后插操作
  • 其他插入操作,都可以转换成后插操作

在这里插入图片描述


4. 双链表的删除

在双链表中删除节点的操作相对比较复杂,因为我们需要维护前驱节点和后继节点之间的指针连接。
以下是删除双链表中某个节点的一般步骤:

  1. 首先,找到要删除的节点。
  2. 如果要删除的节点是头节点,将头节点指针指向下一个节点,并更新下一个节点的前驱指针为 nullptr。
  3. 如果要删除的节点是尾节点,将前一个节点的后继指针设为 nullptr,并更新尾节点指针为前一个节点。
  4. 如果要删除的节点既不是头节点也不是尾节点,将前一个节点的后继指针指向要删除节点的后一个节点,将后一个节点的前驱指针指向要删除节点的前一个节点。
  5. 释放要删除的节点的内存空间。
//删除p的后继结点q, 如下图所示
p->next = q->next;
q->next->prior = p;
free(q);

在这里插入图片描述


在实际使用中,应该确保要删除的节点在链表中确实存在。如果删除的节点不存在于链表中,需要根据具体的需求进行错误处理。同时,删除节点后必须确保释放相应的内存空间,以防止内存泄漏问题的发生。

删除q结点

在这里插入图片描述

将 p 结点的next指针,指向q结点的后继结点。

在这里插入图片描述

释放 q 结点空间

在这里插入图片描述

3.1 删除p结点的后继结点

//删除p结点的后继结点
bool DeleteNextDNode(DNode *p)
{if(p==NULL)		return false;DNode *q = p->next;			//找到p的后继结点if(q==NULL)return false;		//p没有后继结点p->next = q->next;if(q->next != NULL)		//q结点不是最后一个结点q->next->prior = p;	free(q);		//释放结点空间return true;	//删除成功	
}

3.2 销毁一个双链表

//销毁一个双链表
void DestoryList(DLinkList &L)
{//循环释放各个数据结点while(L->next != NULL)    //判断头结点是否有后继结点,直到头结点后再无其他结点结束循环{DeleteNextDNode(L);    //删除p结点的后继结点}free(L);	//释放头结点L = NULL;		//头指针指向NULL	
}

5. 双链表的遍历

4.1 后向遍历

while(p != NULL)
{//对结点p做相应处理,如打印p = p->next;
}

4.2 前向遍历

while(p != NULL)
{//对结点p做响应处理p = p->prior;
}

4.3 前向遍历(跳过头结点)

while(p->prior != NULL)  //当前驱为NULL时,此时遍历到第一个结点,退出循环,跳过了头结点。
{//对结点p做相应处理p = p->prior;
}

双链表不可随机存取,按位查找、按值查找操作都只能用遍历的方式实现,时间复杂度为O(n)


6. 知识点回顾

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/180610.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Synchronized与锁升级

一:java对象内存布局 对象在堆内存的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data) 和对齐填充 二:对象在堆内存中的存储布局 三:Sychronized的锁升级 S…

使用vscode实现远程开发,并通过内网穿透在公网环境下远程连接

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

中文大语言模型汇总

推荐一篇非常棒的github:Awesome-Chinese-LLM 另附语言模型排行榜:FastChat 里面总结了几乎所有目前主流的中文大语言模型。在此记录一下,方便以后慢慢学习。

Adobe After Effects 2024(Ae2024)在新版本中的升级有哪些?

After Effects 2024是Adobe公司推出的一款视频处理软件,它适用于从事设计和视频特技的机构,包括电视台、动画制作公司、个人后期制作工作室以及多媒体工作室。通过After Effects,用户可以高效且精确地创建无数种引人注目的动态图形和震撼人心…

串口代码整合2-如何接收数据?

本文为博主 日月同辉,与我共生,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步! > 发布人:日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

基于SSM的搬家预约系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

阿里云安全恶意程序检测

阿里云安全恶意程序检测 赛题理解赛题介绍赛题说明数据说明评测指标 赛题分析数据特征解题思路 数据探索数据特征类型数据分布箱型图 变量取值分布缺失值异常值分析训练集的tid特征标签分布测试集数据探索同上 数据集联合分析file_id分析API分析 特征工程与基线模型构造特征与特…

List 接口常用实现类底层分析

一、集合 1.1 简介 集合主要分为两组(单列集合、双列集合),Collection 接口有两个重要的子接口 List 和Set,它们的实现子类都是单列集合。Map 接口的实现子类是双列集合,存放的是 K-V 1.2 关系图 二、Collection 接口…

openLayers--绘制多边形、获取视图的中心点、获取当前地图等级、设置地图等级

openLayers绘制多边形、获取视图中心点 前言效果图1、导入LineString2、创建添加多边形3、定义多变形样式4、获取当前视图的中心点5、获取当前视图等级6、设置地图等级 前言 上一篇文章在vue项目中绘制了openlayers绘制了地图和标记点,本篇文章讲解openlayers绘制多…

【IDEA使用maven package时,出现依赖不存在以及无法从仓库获取本地依赖的问题】

Install Parent project C:\Users\lxh\.jdks\corretto-1.8.0_362\bin\java.exe -Dmaven.multiModuleProjectDirectoryD:\学习\projectFile\study\study_example_service "-Dmaven.homeD:\Program Files\JetBrains\IntelliJ IDEA2021\plugins\maven\lib\maven3" "…

独创改进 | RT-DETR 引入双向级联特征融合结构 RepBi-PAN | 附手绘结构图原图

本专栏内容均为博主独家全网首发,未经授权,任何形式的复制、转载、洗稿或传播行为均属违法侵权行为,一经发现将采取法律手段维护合法权益。我们对所有未经授权传播行为保留追究责任的权利。请尊重原创,支持创作者的努力,共同维护网络知识产权。 文章目录 YOLOv6贡献RepBi-…

vuepress使用及拓展(骚操作)

官网 文章目录 背景问题思考方案思索实现方案实现结果存在问题 背景 当前开放平台文件静态保存在前端项目,每次修改都需要通过修改文件发版的方式,很不便利。 1、需要前端手动维护 2、每次小的修改都要发版 随着对接业务的增多,对接文档的变…

【教3妹学编程-算法题】117. 填充每个节点的下一个右侧节点指针 II

2哥 : 3妹,听说你昨天去面试了,怎么样啊? 3妹:嗨,别提了,让我回去等通知,估计是没有通知了, 还浪费我请了一天假。 2哥 : 你又请假了啊, 你是怎么跟你那个严厉的老板请假…

一天写一个(前端、后端、全栈)个人简历项目(附详源码)

一、项目简介 此项目是用前端技术HTMLCSSjquery写的一个简单的个人简历项目模板,图片可点击放大查看,还可以直接下载你的word或者PDF的简历模板。 如果有需要的同学可以直接拿去使用,需自行填写个人的详细信息,发布,…

ChinaSoft 论坛巡礼 | CCF-华为胡杨林基金-系统软件专项(海报)论坛

2023年CCF中国软件大会(CCF ChinaSoft 2023)由CCF主办,CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办,将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

自动驾驶学习笔记(六)——Apollo安装

#Apollo开发者# 学习课程的传送门如下,当您也准备学习自动驾驶时,可以和我一同前往: 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 Apollo安装 硬件配置 安装Ubuntu…

手机转接器实现原理,低成本方案讲解

USB-C PD协议里,SRC和SNK双方之间通过CC通信来协商请求确定充电功率及数据传输速率。当个设备需要充电时,它会发送消息去给适配器请求充电,此时充电器会回应设备的请求,并告知其可提供的档位功率,设备端会根据适配器端…

USB PD v1.0快速充电通信原理

1 原理 本篇文章讲的快速充电是指USB论坛所发布的USB Power Delivery快速充电规范(通过VBUS直流电平上耦合FSK信号来请求充电器调整输出电压和电流的过程),不同于本人发布的另一篇文章所讲的高通Quick Charger 2.0规范,因为高通QC…

虹科示波器 | 汽车免拆检修 | 2012 款上汽大众帕萨特车 发动机偶尔无法起动

一、故障现象 一辆2012款上汽大众帕萨特车,搭载CFB发动机,累计行驶里程约为12万km。车主反映,将点火开关置于起动挡,偶尔只能听到“咔哒”一声,起动机没有反应,类似蓄电池亏电时起动发动机的现象。为此&…

【广州华锐互动】VR历史古城复原:沉浸式体验古代建筑,感受千年风华!

在科技日新月异的今天,虚拟现实(VR)技术已经成为了我们生活中不可或缺的一部分。从娱乐游戏到医疗健康,从教育培训到房地产销售,VR技术的应用领域日益广泛。而近年来,VR技术在文化遗产保护和古迹复原方面的…