数据结构之线性表(一般的线性表)
前言
接下来就开始正式进入数据结构环节了,我们先从线性表开始。
线性表
线性表(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进行部署,在本地测试没有一点问题没有,前脚刚把后端部署到服务器,后脚测试就出现了问题!查看控制台报错提示跨域错误?但是对于静态资源请求,包括登…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
