数据结构之线性表(一般的线性表)
前言
接下来就开始正式进入数据结构环节了,我们先从线性表开始。
线性表
线性表(linear list)也叫线性存储结构,即数据元素的逻辑结构为线性的数据表,它是数据结构中最简单和最常用的一种存储结构,专门存储“一对一”逻辑关系的数据。何为“一对一”?即除去第一个和最后一个数据元素,其他元素均首尾相通,第一个元素只有下家没有上家,最后一个元素只有上家而没有下家。
此外还有一种特殊的线性表——循环链表,其将尾指针指向首元素从而形成了一个闭环。存储在同一个线性表中的数据,其类型必须一致,即要么都是整型,要么都是字符串型。如果从数据结构的逻辑层次上讲,那么线性表还可以进一步细分为一般线性表和受限线性表。
一般的线性表
一般线性表可分为顺序表和链表,链表又可分为单向链表、双向链表和循环链表等,如下图所示。

1. 順序表
如下图所示。

顺序表(Sequential List) 也叫顺序存储结构,即将数据依次存储在连续的物理空间中,是不是发现这样的结构很熟悉?是的,顺序表最底层的结构即为我们常听说的数组(Array),而针对顺序表的任何操作(包括查找、添加和删除等)都是基于遍历。
一般情况下,顺序表申请的存储容量应大于顺序表的长度。
2. 链表
链表(Linked List)也叫链式存储结构,即将数据依次存储在分散的物理空间中,但其逻辑关系仍是连续的,如下图所示。

与顺序表不同,链表的数据元素是随机存储的,因此其物理存储空间比较散乱,但其凭借着一条连接各个数据元素的线条,使数据元素之间保持着一定的逻辑关系。
链表还可细分为单向链表、双向链表和循环链表等,接下来让我们逐一进行学习。
(1)単向链表
单向链表也叫单链表,是链表中最基础的类型,通过单链表开启对于链表的学习,显然是明智的。
上面我们讲到,链表的物理存储空间是不连续的,但逻辑关系却可以保持。这是如何实现的呢?答案是指针域。单链表为每个元素配备了一个指针域(next),指向自己的直接后继元素。
直接后继元素即目标元素后相邻的一个元素,相似的还有后继元素、前驱元素和直接前驱元素。
因此,单链表的数据元素结构应该包含数据域(data)和指针域(next),它们也称为节点,如下图所示。

整个单链表的结构如下图所示

然而完整的链表结构应该有头节点、头指针和首元节点,如下图所示。

- 头指针:指向链表第一个节点(头节点或首元节点)的指针,用于指明链表的位置;
- 头节点:链表第一个不包含数据的空节点,不是必需的;
- 首元节点:链表第一个包含数据的节点,不过作用不如头节点大。
若有头节点,则头指针指向头节点;若无头节点,则头指针指向首元节点。
单链表中的动态和静态
在单链表中又有动态和静态之分。
动态链表也叫动态单链表,很多时候人们还会把它直接称作单链表,这也导致很多人都会把链表的关系树混淆。不过,动态链表确实就是单链表,因此在后面的文章中笔者将会把动态链表称为单链表。
我们已经讲解了顺序表和单链表,而静态链表可以理解为顺序表和单链表的结合体。
静态链表融合了顺序表和单链表的优点——既可快速访问元素,又可快速增加和删除元素。这是怎么做到的呢?
在静态链表中,数据依旧存储在数组中(和顺序表一样),物理空间也是连续的(和顺序表一样),但存储位置是随机的(和单链表一样),元素的逻辑关系则靠“游标”(指针)进行维持(和单链表一样)。
是不是感觉有点懵?别急,我们继续往下看。假设我们创建了一个长度为5的静态链表,它的基础结构如下图所示。

上图所示的是一个空数组。我们进一步剖析一下:一个静态链表,应该是由数据链表和备用链表组成的才对。为了方便理解,我们进一步假设这个长度为5的静态链表存储的是数据{1,2,3},则存储状态可能如下图所示。
通常,备用链表表头指向a[0]的位置,而数据链表表头指向 a[1]的位置。

这里的数据链表即为存储数据的链表。该链表的每个节点除了包含所存储的数据(如1、2、3)之外还拥有一个整型变量,这个变量称为游标变量,用于标记该节点的直接后继节点的位置下标(如2、4、0)。而备用链表则是记录空闲位置的链表。通过备用链表,我们可以清晰、便捷地知道目标链表是否还有空余位置,还可以快速又准确地找到空余位置的物理地址。静态链表的完整结构如下图所示。

在这个例子里,数据链表依次连接的是 a[1]、a[2]、a[4],而备用链表依次连接的是a[0]、a[3]。在静态链表中,a[0]位置默认是不存储数据的,若 a[0]位置有数据,则说明该数组已满,即链表已满。
让我们将数据链表和备用链表结合起来,便可以得到如上图所示存储{1,2,3}的静态链表的完鏊结构。
- 当想要查找元素时,便从数据链表的a[1]位置开始遍历,毕竟我们只知道a[0]和 a[1]的地址;
- 当想要修改元素时,我们依旧从数据链表的a[1]位置开始遍历,找到目标元素后直接修改它的数据域即可,游标不用修改;
- 当想要增加元素时,默认插入位置为备用链表a[0]的直接后继节点,这样就不用移动游标,时间复杂度仅为 O(1);
- 当想要删除元素时,我们先找到目标元素,将其直接前驱节点的游标指向其直接后继节点,然后删除该节点,并将空余位置存放于备用链表中,方便下次使用。
(2)双向链表
有单向链表则必有双向链表,双向链表也叫双链表。无论是我们学过的单链表还是静态链表,节点中都只包含一个指针(游标),用于指向直接后继节点,这确实解决了最基本的“一对一”问题。
当我们编写算法需要多次查找目标节点的前驱节点时,如果使用单链表的话问题就严重了——效率超低!因为单链表是“一根筋的憨憨”,更适合“从前往后”进行遍历。
那怎么办呢?这时候双链表就诞生了。双链表的存储结构和单链表基本一致,只是一个箭头变成了两个而已,这里就不赘述了。双链表的节点结构如下图所示。

双链表的每个节点都有一个数据域和两个指针域,prior 指针指向直接前驱节点,next指针指向直接后继节点。
虽然双向链表的逻辑关系是双向的,但通常情况下,头指针依旧只有一个。
(3)循环链表
循环链表,即环状链表,只是把单链表最后一个节点的指针指向了第一个节点(头节点或首元节点),形成一个头尾相接的环状链表,像个圆圈一样,因此也被称为“环”。
循环链表之下还有单向循环链表和双向循环链表。
单向循环链表:与动态单链表一样,单向循环链表也经常被简单称为循环链表。为了方便大家理解,画了一个循环链表的整体结构图,如下图所示。

双向循环链表:有了对从单链表到循环链表变形过程的认知,相信双向循环链表也就不难理解了。这里就作为作业,读者可尝试一下把双向循环链表的整体结构完整地画出来。
拓展
说到循环链表,提到了环,就必然会想到约瑟夫环。大家可以试着实现约瑟夫环,以加深自己对链表的理解。
相关文章:
数据结构之线性表(一般的线性表)
前言 接下来就开始正式进入数据结构环节了,我们先从线性表开始。 线性表 线性表(linear list)也叫线性存储结构,即数据元素的逻辑结构为线性的数据表,它是数据结构中最简单和最常用的一种存储结构,专门存…...
uniapp安卓android离线打包本地打包整理
离线打包准备 下载Android studio 1.准备资源hbuilder 2.准备离线SDK 最新android平台SDK下载最新android平台SDK下载 3.离线打包key申请 4.直接导入HBuilder-Integrate-AS工程,直接运行simpleDemo项目即可 5.安装java 1.8 jdk-8u151-windows-x64 6.遇到这个报错报错Caus…...
vmware安装centos8-stream
VMware与CentOS8-stream的配置教程【2022-9-5】_centos stream 8-CSDN博客 启动进入后配置网络,/etc/sysconfig/network-scripts/网卡 vmware上的centos8没有网络_主机时wifi上网,centos 8 安装后无法连接网络 解决办法-CSDN博客 centos8配置网络_centos8网络配置…...
使用HttpServletRequestWrapper解决web项目request数据流无法重复读取的问题
在做web项目开发时,我们有时候需要做一些前置的拦截判断处理,比如非法参数校验,防攻击拦截,统一日志处理等,而请求参数如果是form表单提交还好处理;对于json这种输入流的数据就会有问题,统一处理…...
从CNN ,LSTM 到Transformer的综述
前情提要:文本大量参照了以下的博客,本文创作的初衷是为了分享博主自己的学习和理解。对于刚开始接触NLP的同学来说,可以结合唐宇迪老师的B站视频【【NLP精华版教程】强推!不愧是的最完整的NLP教程和学习路线图从原理构成开始学&a…...
Git学习笔记:1 基础命令详解
文章目录 Git基础命令详解: Git基础命令详解: git commit 用法:git commit -m "commit message"功能:将暂存区(stage)中的所有更改提交到本地仓库的当前分支,同时提供一个简短的提交信…...
【服务器】安装宝塔面板
目录 🌺【前言】 🌼【前提】连接服务器 🌷方式一 使用工具登录服务器如Xshell 🌷方式二 阿里云直接连接 🌼 1. 安装宝塔 🌷获取安装脚本 方式一 使用下面提供的脚本安装 方式二 使用官网提供的脚本…...
开源模型应用落地-业务优化篇(一)
一、前言 通过参与“开源模型应用落地-业务整合系列篇”的学习,我们已经成功建立了基本的业务流程。然而,这只是迈出了万里长征的第一步。现在我们要对整个项目进行优化,以提高效率。我们计划利用线程池来加快处理速度,使用redis来实现排队需求,以及通过多级环境来减轻负载…...
【遥感专题系列】影像信息提取之——基于专家知识的决策树分类
可以将多源数据用于影像分类当中,这就是专家知识的决策树分类器,本专题以ENVI中Decision Tree为例来叙述这一分类器。 本专题包括以下内容: 专家知识分类器概述知识(规则)定义ENVI中Decision Tree的使用 概述 基于知…...
lqb日志08
一只小蒟蒻备考蓝桥杯的日志 文章目录 笔记坐标相遇判断工作调度问题(抽象时间轴绘制) 刷题心得小结 笔记 坐标相遇判断 我是小懒虫,碰了一下运气,开了个“恰当”的数(7000)如果,7000次还不能…...
SAP EXCEL上传如何实现指定读取某一个sheet页(ALSM_EXCEL_TO_INTERNAL_TABLE)
如何读取指定的EXCEL sheet 页签,比如要读取下图中第二个输出sheet页签 具体实现方法如下: 拷贝标准的函数ALSM_EXCEL_TO_INTERNAL_TABLE封装成一个自定义函数ZCALSM_EXCEL_TO_INTERNAL_TABLE 在自定义函数导入参数页签新增一个参数SHEET_NAME 在源代码…...
奇怪问题说 - 测试篇
文章目录 1.什么是软件测试2.软件测试和开发的区别3.软件测试的发展:4.软件测试岗位5.软件测试在不同类型公司的定位6.一个优秀的软件测试人员具备的素质6.1综合能力6.2掌握自动化测试技术6.3优秀的测试用例设计能力6.4探索性思维6.5有责任感和一定的压力 7.软件测试…...
中国新能源汽车持续跑出发展“加速度”,比亚迪迎来向上突破
2023年已经过去,对于汽车圈而言,2023年是中国车市的分水岭,在这一年,中国汽车工业70年以来首次进入全球序列,自主品牌强势霸榜,销量首次超过合资车。要知道,这是自大众于1984年进入中国市场成立…...
chatGPT辅助写硕士毕业论文
一、写作顺序 1.标题、研究问题、研究方法 2.文献综述(占比1/5-1/6) 3.论证章节 4.结论、不足、启示 5.处理图表、参考文献的格式 6.绪论或引言 7.摘要、关键词 8.查重、装订 http://【硕士毕业论文写不下去,多亏听了张博士的论文写…...
搭建nginx图片服务器
(1)将图片存储于/home/data/images目录; (2)配置nginx.conf user nginx; worker_processes 4;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 10000; }ht…...
大数据学习之Flink算子、了解DataStream API(基础篇一)
DataStream API (基础篇) 注: 本文只涉及DataStream 原因:随着大数据和流式计算需求的增长,处理实时数据流变得越来越重要。因此,DataStream由于其处理实时数据流的特性和能力,逐渐替代了DataSe…...
js中字符串string,遍历json/Object【匹配url、邮箱、电话,版本号,千位分割,判断回文】
目录 正则 合法的URL 邮箱、电话 字符串方法 千位分割:num.slice(render, len).match(/\d{3}/g).join(,) 版本号比较 判断回文 json/Object 遍历 自身属性 for...inhasOwnProperty(key) Object.获取数组(obj):Object.keys,Object…...
字符串和C预处理器
本文参考C Primer Plus第四章学习 文章目录 常量和预处理器const限定符 1. 常量和预处理器 有时,在程序中要使用常量。例如,可以这样计算圆的周长: circumference 3.14159 * diameter; 这里,常量3.14159 代表著名的常量 pi(π)。…...
Ultraleap 3Di新建项目之给所有的Joint挂载物体
工程文件 Ultraleap 3Di给所有的Joint挂载物体 前期准备 参考上一期文章,进行正确配置 Ultraleap 3Di配置以及在 Unity 中使用 Ultraleap 3Di手部跟踪 新建项目 初始项目如下: 新建Create Empty 将新建的Create Empty,重命名为LeapPro…...
关于session每次请求都会改变的问题
这几天在部署一个前后端分离的项目,使用docker进行部署,在本地测试没有一点问题没有,前脚刚把后端部署到服务器,后脚测试就出现了问题!查看控制台报错提示跨域错误?但是对于静态资源请求,包括登…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...
【java面试】微服务篇
【java面试】微服务篇 一、总体框架二、Springcloud(一)Springcloud五大组件(二)服务注册和发现1、Eureka2、Nacos (三)负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...
