趣说数据结构 —— 3.线性表中的循环链表与双向链表

news2024/11/26 9:44:42

本节介绍线性表中的循环链表与双向链表,主要包括基本结构,主要特点以及适用场景三部分内容。

3.1 循环链表与双向链表

循环链表(Circular Linked List) 是另一种形式的链式存储结构。其特点是表中 最后一个结点的指针域指向头结点,整个链表形成一个环。

在这里插入图片描述
双向链表(Double Linked List) 指的是每个结点都具有两个指针域分别指向它的前驱结点和后继结点的链表。

在这里插入图片描述

3.2 单链表、循环列表与双向列表特点比较

链表名称查找表头结点查找表尾结点查找结点 *p 的前驱结点
带头结点的单链表LL->next
时间复杂度O(1)
从 L->next依次向后遍历
时间复杂度O(n)
通过 p->next无法找到其前驱
带头结点仅设头指针L的
循环单链表
L->next
时间复杂度O(1)
从 L->next依次向后遍历
时间复杂度O(n)
通过 p->next可以找到其前驱
时间复杂度O(n)
带头结点仅设尾指针R的
循环单链表
R->next
时间复杂度O(1)
R
时间复杂度O(1)
通过 p->next可以找到其前驱
时间复杂度O(n)
带头结点的双向
循环单链表L
L->next
时间复杂度O(1)
L->prior
时间复杂度O(1)
通过 p->prior可以找到其前驱
时间复杂度O(1)

这个地方需要画画图理解一下。比如不管是哪一种链表,查找表头结点方法都很简单 L − > n e x t L->next L>next,所以时间复杂度为 O ( 1 ) O(1) O(1),因为四种链表都满足 L->next 就表示第一个结点;

而查找表尾结点同样容易理解,除了循环单链表,其他的都需要 O ( n ) O(n) O(n) 的时间复杂度;

查找结点 *p 的前驱结点这种情况下毫无疑问只有双向循环链表最合适,直接存储了前驱的指针地址,所以找到前驱的时间复杂度为 O(1)

3.3 适用场景

在3.2中提到过三种不同链表不同需求下的时间复杂度,这里我们可以归纳一下在什么情况下我们应当使用循环链表和双向链表。

“适用” 这个词必须跟 “需求” 紧密绑定在一起,所以这里我们得从需求的角度出发分析它们的适用场景。

3.3.1 单链表

各个数据元素之间具有明确的顺序关系,并且逆向关系的通讯需求较低时适合选择使用单链表。比如说考试的时候常常是坐前排的把试卷发给后面一排的,比如说我们的在存储小伙伴的电话号码的时候一般也是按顺序输入,很少有逆序输入的需求。

如果有这种逆序查找或通讯的需求,那么需要考虑这种需求多不多,如果经常发生后排的同学向前排的同学请教问题,那么如果是单链表的话就比较麻烦了,后排的同学必须把问题(也就是数据)取出来,然后从链表表头开始向后面寻找,找到自己前排的同学然后询问问题。

3.3.2 循环链表

循环链表是一种特殊类型的链表,它的最后一个节点指向第一个节点,形成了一个环形结构。与单向链表和双向链表相比,循环链表具有以下优点:

  1. 方便的循环操作:由于循环链表是一个环形结构,因此在处理需要循环遍历的问题时,使用循环链表比使用单向链表或双向链表更方便。

  2. 实现轮流访问:在某些场景中,需要轮流访问某个数据集中的元素,循环链表是一种非常有效的实现方式。例如,计算机操作系统的进程调度算法中,就可以使用循环链表来实现轮流访问各个进程。

  3. 优化内存使用:如果在某些场景中需要频繁地在链表的头尾进行插入和删除操作,使用循环链表比单向链表和双向链表更优,因为可以避免创建新的节点和释放已有节点的内存。

因此,循环链表在需要循环遍历链表、需要轮流访问数据集中的元素、需要频繁在链表头尾进行插入和删除操作的场景下是非常有用的。例如,游戏开发中的动画循环播放功能就可以使用循环链表来实现。

当最后一位元素需要访问链表中第一个元素时,或者当前结点 *p 不清楚自己的相对位置,并且需要从这个结点出发访问整个链表的时候,需要考虑使用循环链表。

比如我们小伙伴们围成一圈,玩 “数到 3 退出圈” 的游戏。那么这个时候我们并不清楚是谁开始数 “1” 的了,每次数到3的小伙伴离圈以后,都从新开始从 1 开始数,所以这个时候使用循环链表更加符合实际需求,操作起来也较为方便。

但对于有明确的 “终止元素” 的链表,不可使用循环链表以避免出现 “死循环” 的现象。

3.3.3 双向链表

双向链表是一种数据结构,它具有单向链表的所有特性,但是每个节点除了指向下一个节点的指针之外,还有指向前一个节点的指针。这使得双向链表具有许多优点,例如:

  1. 插入和删除操作:由于每个节点都有指向前一个节点的指针,因此在双向链表中插入或删除一个节点比单向链表更容易和更高效。例如,删除节点时,可以直接通过前一个节点的指针找到需要删除的节点,而无需遍历整个链表。

  2. 遍历操作:由于双向链表可以从前往后或从后往前遍历,因此在某些情况下,使用双向链表比单向链表更方便。例如,当需要在链表中查找某个节点的前一个节点时,双向链表比单向链表更快。

链表中相邻元素相互访问密切时,考虑使用双向链表。比如说我们在搜索两个地方之间的距离的时候,对应的数据应当是一个 “无向图”,也就是说,两个点之间都是相互的,A地点与B地点之间的距离,等于B地点与A地点的距离,相互前往都是可能的,所以我们考虑使用双向链表。

比如说你和你的同桌,两个人总是打打闹闹的,这节课他找你借个圆规,下节课你找他借个橡皮;这节课你抄他数学题课后作业,下节课你帮他补习英语完形填空…… 这种双向关系更加适合使用双向链表,通讯更加简单方便 —— 不至于常常需要从头结点开始查。

3.4 总结

本章主要总结一些面试官可能问到的问题或者是考试可能考到的问题,事实上理解清楚了基本上就差不多了,一定需要跟面试的老师(考研)或是面试官(工作)说清楚这个数据结构的主要特点,讲清楚以后一般就足够了,面试官没心思听太仔细的东西。

Smileyan
2023.04.29 23:41

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sklearn.metrics 中的f1-score介绍

1 f1_score,averagebinary, macro, micro, weighted F1得分可以解释为精确度和召回率的调和平均值,其中F1得分达到其最佳值为1,最差得分为0。精确度和召回率对F1得分的相对贡献相等。F1得分的公式为: 在多类别和多标签的情况下,这…

4.30学习周报

文章目录 前言文献阅读摘要简介数据源和预处理理论基础与模型构建结果和讨论结论和未来工作 时间序列预测总结 前言 本周阅读文献《Water Quality Prediction Based on LSTM and Attention Mechanism: A Case Study of the Burnett River, Australia》,文献主要提出…

SOLIDWORKS培训|弧长如何标注

大家在使用SolidWorks软件时,如果想对不同形状的弧长度进行标注,可以试试以下方法。 ◉ 标注圆弧 点四下鼠标,需要点击弧线和两个端点。 我们先使用圆心起点圆弧工具绘制一个圆弧。 然后点击智能尺寸,点击圆弧,没错…

【Python_Opencv图像处理框架】信用卡数字识别项目

写在前面 本篇文章是opencv学习的第六篇文章,前面主要讲解了对图像的一些基本操作,这篇文章我们就开始大展身手,将前面所学的基础操作活学活用。既能复习基础操作,又能学到一些新的知识。作为初学者,我尽己所能&#…

Change Buffer详解

change Buffer基本概念 Change Buffer:写缓冲区,是针对二级索引(辅助索引) 页的更新优化措施 作用: 在进行DML(写)操作(insert/update/delete)时,如果请求的是 辅助索引(非唯一键索引)没有在缓冲池 中时,并不会立刻将…

多态

一、多态性概述 1、静态多态实现的两种方式:模板和函数重载 2、动态多态(一般上所说的多态都是指动态多态) 示例: 若执行pa->f(pa),则由动态编联找到派生类,而pa静态类型为A*,所以输出3若执行…

notepad++安装HexEditor插件查看二进制文件

文章目录 前言一、下载 HexEditor 插件二、解压文件三、将插件放置到 plugins 目录下四、重启软件测试 前言 有时候我们需要分析二进制文件,但是分析二进制文件直接用编辑器查看会出现乱码的情况,本文在 notepad 软件上安装一个 HexEditor 插件&#xf…

【Java笔试强训 19】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥汽水瓶 …

各大“排序”特性及稳定性总结

一、各个排序特性 二、各个排序的稳定性分析及例子 稳定性如何定义:排序算法的稳定性并不是指它在对数组进行排序的时候的时间复杂度是否变化,而是对于相同数值的数据进行排序了之后它们的相对位置是否发生了变化,比如说在考试的时候…

【Java笔试强训 18】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥统计每…

【Java笔试强训 16】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、判断题 🔥完全数计…

JAVA入坑之JAVADOC(Java API 文档生成器)与快速生成

目录 一、JAVADOC(Java API 文档生成器) 1.1概述 1.2Javadoc标签 1.3Javadoc命令 1.4用idea自带工具生成API帮助文档 二、IDEA如何生成get和set方法 三、常见快捷方式 3.1快速生成main函数 3.2快速生成println()语句 3.3快速生成for循环 3.4“…

【Python】序列类型①-列表

文章目录 1. 前言2. 列表的定义3. 列表的下标访问3.1 嵌套列表的下标 4. 列表的切片操作5. 列表的遍历5.1 使用for循环进行遍历5.2 while循环进行遍历 6.添加列表元素6.1 使用append方法添加元素6.2 使用insert方法添加元素 7. 列表的拼接7.1 使用 进行拼接7.2 使用extend 进行…

( 字符串) 696. 计数二进制子串 ——【Leetcode每日一题】

❓696. 计数二进制子串 难度:简单 给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的。 重复出现(不同位置&#xff09…

动态规划01背包问题

01背包问题 假设你是一名经验丰富的探险家,背着背包来到野外进行日常探险。天气晴朗而不燥热,山间的风夹杂着花香,正当你欣赏这世外桃源般的美景时,突然,你发现了一个洞穴,这个洞穴外表看起来其貌不扬&…

UE动画状态机的事件触发顺序测试

正常A状态过渡到B状态的事件顺序: 整个流程为: 调用B状态的On Become Relevant事件调用B状态的On Update事件调用A状态的Left State Event事件调用B状态的Entered State Event事件调用B状态的Start Transition Event事件调用B状态的End Transition Even…

网络安全:通过445端口暴力破解植入木马。

网络安全:通过445端口暴力破解植入木马。 木马制作工具,如:灰鸽子等等 445端口是文件共享端口。可以进入对方文件硬盘进行植入木马: 使用文件共享进入对方磁盘: 在cmd输入net use \\x.x.x.x\ipc$ 之后会让你输入账号…

Vue——组合式函数

目录 什么是“组合式函数”?​ 鼠标跟踪器示例​ 异步状态示例​ 约定和最佳实践​ 命名​ 输入参数​ 返回值​ 副作用​ 使用限制​ 通过抽取组合式函数改善代码结构 选项式 API 中使用组合式函数​ 与其他模式的比较​ 和 Mixin 的对比​ 和无渲染…

mybatis逆向生成器

目录 官网xml pom引入 在resources新建generatorConfig.xml xml修改 生成 官网xml MyBatis Generator Core – MyBatis Generator XML Configuration File Reference pom引入 <!-- mybatis逆向生成器 --><dependency><groupId>org.mybatis.gener…

anaconda 共享虚拟环境

需求背景 A,B,C… 多台服务器。 有一个公共的NAS服务器N&#xff0c;存储所有数据资料。 N分别挂载到A,B,C…服务器上&#xff0c;便于所有服务器访问数据。 挂载路径在所有服务器上统一为/nas/。 现状&#xff1a; A,B,C&#xff0c;… 上分别安装anaconda&#xff0c;分别创…