线性表(顺序表,单链表,双链表,循环链表,静态链表)

news2024/11/25 16:52:20

目录

  • 1.线性表的定义
    • 1.几个重要的概念
    • 2.逻辑结构
  • 2.线性表的基本操作
  • 3.顺序表(线性表的顺序存储)
    • 1.静态分配
    • 2.动态分配
    • 3.顺序表的特点
    • 4.顺序表的基本操作
      • 1.插入
      • 2.删除
      • 3.查找
        • 1.按位查找
        • 2.按值查找
  • 4.链表(线性表的链式存储)
    • 1.单链表
      • 1.代码实现
      • 2.带头结点的实现
      • 3.不带头结点的实现
      • 4.按位序插入
      • 5.指定结点的后插操作
      • 6.指定结点的前插操作
      • 7.按位序删除
      • 8.指定结点的删除
      • 9.按位查找
      • 10.按值查找
      • 11.求表的长度
    • 2.单链表的建立
      • 1.尾插法
      • 2.头插法
    • 3.双链表
      • 1.初始化
      • 2.插入
      • 3.删除
      • 4.遍历
    • 4.循环链表
      • 1.循环单链表
        • 1.初始化
        • 2.基本操作
      • 2.循环双链表
        • 1.初始化
        • 2.基本操作
    • 5.静态链表
      • 1.定义
      • 2.代码实现
      • 3.基本操作
  • 5.顺序表和链表的对比
    • 1.逻辑结构
    • 2.存储结构
    • 3.基本操作
      • 1.创建
      • 2.销毁
      • 3.增删
      • 4.查找
    • 4.选择

1.线性表的定义

线性表是具有相同数据类型的n (n>=0)个数据元素的有限序列,其中n为表长,当n = 0时线性表是一个空表。
若用L命名线性表,则其一般表示为 L = ( a 1 , a 2 , . . . , a i , a i + 1 , . . . , a n ) L= (a1, a2,... , a_i, a_{i+1}, ... , an) L=(a1,a2,...,ai,ai+1,...,an)

1.几个重要的概念

a i a_i ai是线性表中的“第i个”元素线性表中的位序
注意:位序从1开始,数组下标从0开始。
a 1 a_1 a1表头元素;
a n a_n an表尾元素
除第一个元素外,每个元素有且仅有一个直接前驱;
除最后一个元素外,每个元素有且仅有一个直接后继.

2.逻辑结构

在这里插入图片描述

2.线性表的基本操作

“&”符号的作用:对参数的修改结果带回主函数

①InitList(&L):初始化表。构造一个空的线性表L,分配内存空间
②DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占用的内存空间。
③ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e.
④ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。
⑤LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。
⑥GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。
⑦Length(L):求表长。返回线性表L的长度,即L中数据元素的个数。
⑧PrintList(L):输出操作。按前后顺序输出线性表L的所有元素值。
⑨Empty(L):判空操作。若L为空表,则返回true,否则返回false。

3.顺序表(线性表的顺序存储)

顺序表:用顺序存储的方式实现线性表。
顺序存储:把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。
顺序表的实现方式:静态分配和动态分配。

1.静态分配

存储空间是静态的。
使用“静态数组”实现,大小一旦确定就无法改变。

在这里插入图片描述

2.动态分配

C语言中提供malloc和free函数来动态申请和释放内存空间。
使用动态数组实现。
在这里插入图片描述

3.顺序表的特点

随机访问,即可以在(O1)时间内找到第i个元素。
②存储密度高,每个节点只存储数据元素。
③拓展容量不方便(即便采用动态分配的方式实现,拓展长度的时间复杂度也比较高)
④插入、删除操作不方便,需要移动大量元素。

4.顺序表的基本操作

1.插入

在这里插入图片描述

①最好情况:新元素插入到表尾,不需要移动元素。
i = n + 1 i = n+1 i=n+1,循环0次;最好时间复杂度=O(1)
②最坏情况:新元素插入到表头,需要将原有的n个元素全都向后移动。
i = 1 i = 1 i=1,循环n次;最坏时间复杂度= O(n);
③平均情况:假设新元素插入到任何一个位置的概率相同,
i = 1 , 2 , 3 , . . , l e n g t h + 1 的概率都是 p = 1 n + 1 i=1,2,3,.. , length+1的概率都是p=\frac{1}{n+1} i=1,2,3,..,length+1的概率都是p=n+11
平均循环次数= n ( n + 1 ) 2 1 n + 1 = n 2 \frac{n(n+1)}{2}\frac{1}{n+1}=\frac{n}{2} 2n(n+1)n+11=2n平均时间复杂度= O(n)

2.删除

在这里插入图片描述

①最好情况:删除表尾元素,不需要移动其他元素。
i = n,循环0次;最好时间复杂度=O(1)
②最坏情况:删除表头元素,需要将后续的n-1个元素全都向前移动。
i = 1,循环n-1 次;最坏时间复杂度= O(n);
③平均情况:假设删除任何一个元素的概率相同,即 i = 1 , 2 , 3 , . . . , l e n g t h i= 1,2,3,... , length i=1,2,3,...,length的概率都是 p = 1 n p =\frac{1}{n} p=n1
平均循环次数 = n ( n − 1 ) 2 1 n = n − 1 2 \frac{n(n-1)}{2}\frac{1}{n}=\frac{n-1}{2} 2n(n1)n1=2n1平均时间复杂度= O(n)

3.查找

1.按位查找

GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。
由于顺序表的各个数据元素在内存中连续存放,因此可以根据起始地址和数据元素大小立即找到第i个元素:“随机存取”特性。
时间复杂度为O(1)

2.按值查找

LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。
最好情况:目标元素在表头,循环1次;最好时间复杂度=O(1)
最坏情况:目标元素在表尾,循环n 次;最坏时间复杂度= O(n);
平均情况:假设目标元素出现在任何一个位置的概率相同,都是 1 n \frac{1}{n} n1,平均循环次数= n ( n + 1 ) 2 1 n = n + 1 2 \frac{n(n+1)}{2}\frac{1}{n}=\frac{n+1}{2} 2n(n+1)n1=2n+1
平均时间复杂度= O(n)

4.链表(线性表的链式存储)

1.单链表

单链表由一个一个结点组成,每个结点除了存放数据元素外,还要存储指向下一个节点的指针。
优点:不要求大片连续空间,改变容量方便。
缺点:不可随机存取,要耗费一定空间存放指针。

1.代码实现

强调这是一个单链表:使用 L i n k L i s t LinkList LinkList
强调这是一个结点:使用 L N o d e ∗ LNode * LNode
在这里插入图片描述

2.带头结点的实现

头指针本身不存储数据,数据域为空,只有他指向的下一个结点开始存储数据。
在这里插入图片描述

3.不带头结点的实现

不带头结点,写代码更麻烦。
对第一个数据结点和后续数据结点的处理需要用不同的代码逻辑,对空表和非空表的处理需要用不同的代码逻辑。

4.按位序插入

Listlnsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。
①带头结点
在这里插入图片描述
平均时间复杂度:O(n)
②不带头结点
在这里插入图片描述

5.指定结点的后插操作

在这里插入图片描述

6.指定结点的前插操作

①使用带头指针的链表,循环查找元素的前驱,再对元素前驱进行后插操作。
时间复杂度为O(n)
②将新增结点复制为需要进行前插操作的结点,再将待插入的数据的数据域复制给当前结点,连接两个结点即可。
在这里插入图片描述
时间复杂度为O(1)

7.按位序删除

ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。
找到第i-1个结点,将其指针指向第i+1个结点,并释放第i个结点。

①带头结点
在这里插入图片描述
最环、平均时间复杂度:O(n)
最好时间复杂度:O(1)

8.指定结点的删除

删除结点p,需要修改其前驱结点的next指针,
方法1:传入头指针,循环寻找p的前驱结点
方法2:偷天换日(类似于结点前插的实现)
在这里插入图片描述
时间复杂度为O(1),但如果p为最后一个结点时会存在空指针问题

9.按位查找

平均时间复杂度为O(n).

在这里插入图片描述

10.按值查找

平均时间复杂度为:O(n)
在这里插入图片描述

11.求表的长度

平均时间复杂度为:O(n)
在这里插入图片描述

2.单链表的建立

1.尾插法

时间复杂度:O(n)
要设置一个指向表尾结点的指针。

在这里插入图片描述

2.头插法

应用:链表的逆置
在这里插入图片描述

3.双链表

在这里插入图片描述

1.初始化

增加了一个指向前驱的指针域。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.插入

在这里插入图片描述

3.删除

在这里插入图片描述

4.遍历

在这里插入图片描述

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

4.循环链表

1.循环单链表

表尾结点的next指针指向头结点。
从一个结点出发可以找到其他任何一个结点。

在这里插入图片描述

1.初始化

在这里插入图片描述

2.基本操作

①从头结点找到尾部,时间复杂度为O(n)
②从尾部找到头部,时间复杂度为O(1)
③很多时候对链表的操作都是在头部或尾部,可以让L指向表尾元素(插入、删除时可能需要修改L)。

2.循环双链表

表头结点的prior指向表尾结点。
表尾结点的next指向头结点。
在这里插入图片描述

1.初始化

在这里插入图片描述

2.基本操作

①插入
在这里插入图片描述
②删除
在这里插入图片描述

5.静态链表

1.定义

静态链表:分配一整片连续的内存空间,各个结点集中安置。
静态链表:用数组的方式实现的链表。

优点:增、删操作不需要大量移动元素
缺点:不能随机存取,只能从头结点开始依次往后查找。
容量固定不可变
适用场景:
①不支持指针的低级语言;
②数据元素数量固定不变的场景(如操作系统的文件分配表FAT)

在这里插入图片描述

2.代码实现

在这里插入图片描述

3.基本操作

①查找
从头结点出发挨个往后遍历结点。时间复杂度为O(n)

②插入
找到一个空的结点,存入数据元素
从头结点出发找到位序为i-1的结点
修改新结点的next
修改i-1号结点的next

③删除
从头结点出发找到前驱结点
修改前驱结点的游标
被删除结点next设为-2

5.顺序表和链表的对比

1.逻辑结构

都属于线性表,都是线性结构

2.存储结构

①顺序表(顺序存储)
优点:支持随机存取、存储密度高。
缺点:大片连续空间分配不方便,改变容量不方便。

②链表(链式存储)
优点:离散的小空间分配方便,改变容量方便。
缺点:不可随机存取,存储密度低。

3.基本操作

1.创建

①顺序表
需要预分配大片连续空间。
若分配空间过小,则之后不方便拓展容量;
若分配空间过大,则浪费内存资源。
②链表
只需分配一个头结点(也可以不要头结点,只声明一个头指针),之后方便拓展。

2.销毁

①顺序表
修改Length=0
系统自动回收空间

②链表
依次删除各个结点( free )
需要手动free

3.增删

①顺序表
插入/删除元素要将后续元素都后移/前移
时间复杂度O(n)
时间开销主要来自移动元素
若数据元素很大,则移动的时间代价很高

②链表
插入/删除元素只需修改指针即可
时间复杂度o(n)
时间开销主要来自查找目标元素
查找元素的时间代价更低

4.查找

①顺序表
按位查找:O(1)
按值查找:O(n)若表内元素有序,可在 O ( l o g 2 n ) O(log_2n) O(log2n)时间内找到

②链表
按位查找:O(n)
按值查找:O(n)

4.选择

表长难以预估、经常要增加/删除元素—―链表。
表长可预估、查询(搜索)操作较多――顺序表。

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

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

相关文章

HackTheBox-Starting Point--Tier 1---Funnel

文章目录 一 题目二 实验过程三 利用SSH隧道3.1 本地端口转发 一 题目 Tags FTP、PostgreSQL、Reconnaissance、Tunneling、Password Spraying、Port Forwarding、Anonymous/Guest Access、Clear Text Credentials译文:FTP、PostgreSQL、侦察、隧道技术、密码喷洒…

【笔记】判断高电平,低电平和方波的几种方法

读取某一个上拉电平信号,它可能输出是低电平,可能是高电平,可能是方波,并且这个方波不知道频率何占空比,那么如何来通过程序来判断呢?高电平和低电平都好说,利用HAL库读取即可,如下&…

在云上jupylab(codelab)常用的shell命令

1、切换当前文件目录位置: %cd /project/train/ 2、删除目标文件夹和文件夹下面的内容,注意这个r是不能少的: !rm -r /project/train/src_repo/dataset 3、创建数据集相关文件夹 !mkdir /project/train/src_repo/dataset 4、复制指定…

Pytorch tensor 数据类型快速转换三种方法

目录 1 通用,简单,CPU/GPU tensor 数据类型转换 2 tensor.type()方法 CPU tensor 数据类型转换 GPU tensor 数据类型转换 3 tensor.to() 方法,CPU/GPU tensor 数据类型转换 1 通用,简单, CPU/GPU tensor 数据类型转换 tensor.double():…

Educational Codeforces Round 157 (A--D)视频详解

Educational Codeforces Round 157 &#xff08;A--D&#xff09;视频详解 视频链接A题代码B题代码C题代码D题代码 视频链接 Educational Codeforces Round 157 &#xff08;A–D&#xff09;视频详解 A题代码 #include<bits/stdc.h> #define endl \n #define deb(x)…

高频SQL50题(基础版)-2

文章目录 主要内容一.SQL练习题1.577-员工奖金代码如下&#xff08;示例&#xff09;: 2.1280-学生们参加各科测试的次数代码如下&#xff08;示例&#xff09;: 3.570-至少有5名直接下属的经理代码如下&#xff08;示例&#xff09;: 4.1934-确认率代码如下&#xff08;示例&a…

C#,数值计算——偏微分方程,Relaxation的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class Relaxation { private Relaxation() { } public static void sor(double[,] a, double[,] b, double[,] c, double[,] d, double[,] e, double[,] f, double[,] u, double rjac) …

大型Bat面试知识总结分享—AMS在Android起到什么作用?简单的分析下Android的源码

面试官: AMS在Android起到什么作用&#xff0c;简单的分析下Android的源码 心理分析&#xff1a;这道题在发生在大多数场景下。面对这道题 很多求职很茫然&#xff0c;不知道该如何说起。AMS本身比较复杂难以理解。工作多年也很难弄清AMS的作用&#xff0c;其实我们大可从以下几…

企业数字化转型与供应链效率-基准回归复刻(2007-2022年)

参照张树山&#xff08;2023&#xff09;的做法&#xff0c;本团队对来自统计与决策《企业数字化转型与供应链效率》一文中的基准回归部分进行复刻。文章实证检验企业数字化转型对供应链效率的影响。用年报词频衡量上市公司数字化转型程度&#xff0c;以库存周转天数来衡量供应…

大数据疫情分析及可视化系统 计算机竞赛

文章目录 0 前言2 开发简介3 数据集4 实现技术4.1 系统架构4.2 开发环境4.3 疫情地图4.3.1 填充图(Choropleth maps)4.3.2 气泡图 4.4 全国疫情实时追踪4.6 其他页面 5 关键代码最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 大数据疫…

西门子S7-200SMART 通过向导实现S7通信的具体组态步骤示例

西门子S7-200SMART 通过向导实现S7通信的具体组态步骤示例 具体步骤可参考以下内容: 打开编程软件STEP7-Micro/WIN SMART在“工具”菜单的“向导”"区域单击"Get/Put"按钮,启动PUT/GET向导, 在弹出的“Get/Put”向导界面种添加操作步骤名称并添加注释。 点…

洛谷P1102 A-B数对 详细解析及AC代码

P1102 A-B数对 前言题目题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示题目分析注意事项 代码经典二分&#xff08;O(nlgn)&#xff09;酷炫哈希&#xff08;O(n)&#xff09; 后话额外测试用例样例输入 #2样例输出 #2 王婆卖瓜 题目来源 前言 酷&…

OpenAI 年度大戏即将揭晓,5 大剧透全方位曝光

北京时间 11 月 7 日凌晨 2 点&#xff0c;2023 年度最受关注的 AI 活动 OpenAI DevDay 将正式揭晓。2022 年 11 月&#xff0c;OpenAI 正式发布了 ChatGPT&#xff0c;这个改变整个 AI 发展进程和轨迹的颠覆性产品。OpenAI 选择在 ChatGPT 发布一周年之际举行这次活动&#xf…

Git 基础知识回顾及 SVN 转 Git 自测

背景 项目开发过程中使用的版本控制工具是 SVN&#xff0c;Git 多有耳闻&#xff0c;以前也偶尔玩过几次&#xff0c;但是工作中不用&#xff0c;虽然本地也有环境&#xff0c;总是不熟练。 最近看一本网络开源技术书时&#xff0c;下载源码部署了一下&#xff0c;又温故了一…

socket编程中的EINTR是什么?

socket编程中的EINTR是什么? 在socket编程中&#xff0c;我们时常在accept/read/write等接口调用的异常处理的部分看到对于EINTR的处理&#xff0c;例如下面这样的语句&#xff1a; repeat: if(read(fd, buff, size) < 0) {if(errno EINTR)goto repeat;elseprintf("…

时间序列预测中的数据分析->周期性、相关性、滞后性、趋势性、离群值等特性的分析方法

本文介绍 本篇文章给大家介绍的是&#xff0c;当我们在进行有关时间序列相关的工作或者实验时&#xff0c;需要对数据进行的一些数据分析操作(包括周期性、相关性、滞后性、趋势性、离群值等等分析)的方法。在本篇文章中会以实战的形式进行讲解&#xff0c;同时提供运行代码和…

求1~100000之间所有的“水仙花数”,并输出

这里所指的水仙花数&#xff0c;并不是严格意义上的水仙花数&#xff0c;我们先查看一下水仙花数是什么 水仙花数&#xff08;Narcissistic number&#xff09;也被称为超完全数字不变数&#xff08;pluperfect digital invariant, PPDI&#xff09;、自恋数、自幂数、阿姆斯壮…

IOC容器创建bean实例的4种方式

&#x1f388;个人公众号:&#x1f388; :✨✨✨ 可为编程✨ &#x1f35f;&#x1f35f; &#x1f511;个人信条:&#x1f511; 知足知不足 有为有不为 为与不为皆为可为&#x1f335; &#x1f349;本篇简介:&#x1f349; 本篇记录IOC容器创建bean实例的4种方式&#xff0c;…

mysql联合索引和最左匹配问题。

1引言&#xff1a; 如果频繁地使⽤相同的⼏个字段查询&#xff0c;就可以考虑建⽴这⼏个字段的联合索引来提⾼查询效率。⽐如对 于联合索引 test_col1_col2_col3&#xff0c;实际建⽴了 (col1)、(col1, col2)、(col, col2, col3) 三个索引。联合 索引的主要优势是减少结果集数量…

深入理解Python中的布尔值:真与假

Python作为一门强大的编程语言&#xff0c;具有丰富的数据类型和逻辑运算&#xff0c;其中布尔&#xff08;Boolean&#xff09;值在控制程序流程和逻辑决策中扮演着关键的角色。本文将深入探讨Python中的布尔值&#xff0c;解释什么是真&#xff08;True&#xff09;和假&…