线性表(从数据结构的三要素出发)
文章目录
- 逻辑结构
- 存储结构
- 顺序存储
- 链式存储
- 单链表
- 双链表
- 循环单链表
- 循环双链表
- 静态链表
- 数据的操作
- 顺序结构
- 链式结构
- 单链表
- 双链表
逻辑结构
线性表是具有相同数据类型的 n ( n ≥ 0 ) n(n≥0) n(n≥0)个数据元素的有限序列,其中 n n n为表长,当 n = 0 n=0 n=0时线性表是一个空表。若用 L L L命名线性表,则其一般表示为
L = ( a 1 , a 2 , ⋯ , a i , a i + 1 , ⋯ , a n ) L=\left(a_1, a_2, \cdots, a_i, a_{i+1}, \cdots, a_n\right) L=(a1,a2,⋯,ai,ai+1,⋯,an)
式中, a 1 a_1 a1是唯一的“第一个”数据元素,又称表头元素; a n a_n an是唯一的“最后一个”数据元素,又称表尾元素。除第一个元素外,每个元素有且仅有一个直接前驱。除最后一个元素外,每个元素有且仅有一个直接后继。
线性表有以下特性:
- 表中元素的个数有限。
- 表中元素具有逻辑上的顺序性,表中元素有其先后次序。
- 表中元素都是数据元素,每个元素都是单个元素。
- 表中元素的数据类型都相同,这意味着每个元素占有相同大小的存储空间。
- 表中元素具有抽象性,即仅讨论元素间的逻辑关系,而不考虑元素究竟表示什么内容。
存储结构
顺序存储
它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。第1个元素存储在顺序表的起始位置,第i个元素的存储位置后面紧接着存储的是第 i + 1 i+1 i+1个元素,称 i i i为元素 a i a_i ai在顺序表中的位序。因此,顺序表的特点是表中元素的逻辑顺序与其存储的物理顺序相同。
假设顺序表L存储的起始位置为LOC(A)
,sizeof(ElemType)
是每个数据元素所占用存储空间的大小。
typedef struct {ElemType data[Maxsize];int length;
} SqList;
存在的问题:
- 需要大量连续的存储空间
- 插入删除时,时间复杂度高
- 顺序表一旦确定大小,后续将不可扩充
链式存储
链式存储线性表时,不需要使用地址连续的存储单元,即不要求逻辑上相邻的元素在物理位置上也相邻,它通过“链”建立元素之间的逻辑关系,因此插入和删除操作不需要移动元素,而只需修改指针,但也会失去顺序表可随机存取的优点。
单链表
typedef struct LNode {ElemType data;struct LNode *next;
} LNode, *LinkList;
存在的问题:
- 失去了顺序存储中随机存取的特性
- 求表长的时间复杂度高
- 访问前驱结点的时间复杂度高
双链表
在单链表中要访问某个结点的前驱(插入、删除操作时),只能从头开始遍历,访问前驱的时间复杂度为 O ( n ) O(n) O(n)。为了克服单链表的这个缺点,引入了双链表,双链表结点中有两个指针prior
和next
,分别指向其直接前驱和直接后继。表头结点的 prior
域和尾结点的 next
域都是 NULL
。
typedef struct DNode {ElemType data;struct DNode *next, prior;
} DNode, *DLinkList;
循环单链表
循环单链表和单链表的区别在于,表中最后一个结点的指针不是NULL
,而改为指向头结点,从而整个链表形成一个环。
循环双链表
由循环单链表的定义不难推出循环双链表。不同的是,在循环双链表中,头结点的prior
指针还要指向表尾结点。
静态链表
静态链表是用数组来描述线性表的链式存储结构,结点也有数据域data
和指针域 next
,与前面所讲的链表中的指针不同的是,这里的指针是结点在数组中的相对地址(数组下标),又称游标。
typedef struct {ElemType data;int next;
} SLinkList[Maxsize];
数据的操作
顺序结构
初始化
void InitList(SqList &L)
{L.length = 0;
}
判满
bool isFull(SqList L)
{if (L.length == Maxsize) return true;return false;
}
判空
bool isEmpty(SqList L)
{if (L.length == 0) return true;return false;
}
插入操作
bool ListInsert(SqList &L, int i, ElemType e)
{if (i < 1 || i > L.length + 1) // 无效的插入位置return false;if (isFull(L)) return false; // 存储空间已满for (int j = L.length; j >= i; j -- )L.data[j] = L.data[j - 1];L.data[i - 1] = e;L.length ++ ;return true;
}
删除操作
bool ListDelete(SqList &L, int i, ElemType e)
{if (i < 1 || i > L.length + 1) // 无效的删除位置return false;if (isEmpty(L)) return false; // 数组是空的e = L.data[i - 1];for (int j = i; j < L.length; j ++ )L.data[j - 1] = L.data[j];L.length -- ;return true;
}
按值查找
int LocateElem(SqList L, ElemType e)
{for (int i = 0; i < L.length; i ++ )if (L.data[i] == e)return i + 1;return -1;
}
链式结构
单链表
初始化
void InitList(LinkList &L)
{L = (LNode *) malloc (sizeof(LNode));L->next = NULL;
}
求表长
int Length(LinkList L)
{LNode *p = L->next;int cnt = 0; // 记录长度while (p){cnt ++ ;p = p->next;}return cnt;
}
按序号查找结点
LNode * GetElem(LinkList L, int i)
{LNode *p = L->next;int cnt = 0; // 记录当前遍历到第几个结点了while (p){cnt ++ ;if (cnt == i)return p;p = p->next;}return NULL;
}
按值查找
LNode * LocateElem(LinkList L, ElemType e)
{LNode *p = L->next;while (p){if (p->data == e)return p;p = p->next;}return NULL;
}
插入结点
bool ListInsert(LinkList &L, int i, ElemType e)
{LNode *p = L;int j = 0;while (p && j < i - 1){p = p->next;j ++ ;}if (p == NULL) return false; // 位置不合法LNode *s = (LNode *) malloc (sizeof(LNode));/*插入结点*/s->data = e;s->next = p->next;p->next = s;return true;
}
删除结点
bool ListDelete(LinkList &L, int i, ElemType e)
{LNode *p = L;int j = 0;while (p && j < i - 1){p = p->next;j ++ ;}if (p == NULL || p->next == NULL) return false; // 位置不合法LNode *q = p->next;/*删除结点q*/e = q->data;p->next = q->next;free(q);return true;
}
采用头插法建立链表
LinkList List_HeadInsert(LinkList &L)
{LNode *s;int x;L = (LNode *) malloc (sizeof(LNode));L->next = NULL;scanf("%d", &x);while (x != 9999) // 输入9999停止{s = (LNode *) malloc (sizeof(LNode));s -> data = x;s->next = L->next;L->next = s;scanf("%d", &x);}return L;
}
采用尾插法建立链表
LinkList List_TailInsert(LinkList &L)
{int x;L = (LNode *) malloc (sizeof(LNode));LNode *s, *r = L; // r是表尾指针scanf("%d", &x);while (x != 9999) // 输入9999停止{s = (LNode *) malloc (sizeof(LNode));s -> data = x;r->next = s;r = s;scanf("%d", &x);}r->next = NULL;return L;
}
双链表
初始化
void InitList(DLinkList &L)
{L = (DNode *) malloc (sizeof(DNode));L->next = L->prior = NULL;
}
插入结点
bool ListInsert(DLinkList &L, int i, ElemType e)
{DNode *p = L;int j = 0;while (p && j < i - 1){p = p->next;j ++ ;}if (p == NULL) return false; // 位置不合法DNode *s = (DNode *) malloc (sizeof(DNode));/*插入结点*/s->data = e;s->next = p->next;p->next->prior = s;s->prior = p;p->next = s;return true;
}
删除结点
bool ListDelete(DinkList &L, int i, ElemType e)
{DNode *p = L;int j = 0;while (p && j < i - 1){p = p->next;j ++ ;}if (p == NULL || p->next == NULL) return false; // 位置不合法DNode *q = p->next;/*删除结点q*/e = q->data;p->next = q->next;q->next->prior = p;free(q);return true;
}
相关文章:

线性表(从数据结构的三要素出发)
文章目录 逻辑结构存储结构顺序存储链式存储单链表双链表循环单链表循环双链表静态链表 数据的操作顺序结构链式结构单链表双链表 逻辑结构 线性表是具有相同数据类型的 n ( n ≥ 0 ) n(n≥0) n(n≥0)个数据元素的有限序列,其中 n n n为表长,当 n 0 n0…...

[SCTF2019]babyre
打开看看还是有花指令 解除后首先pass1是解maze,好像又是三维的 x是25,也就是向下跳五层,注意是立体的 得到 passwd1: ddwwxxssxaxwwaasasyywwdd 接着往下看 有一个加密函数IDA逆向常用宏定义_lodword-CSDN博客 unsigned __int64 __fastca…...
uniapp实现下拉过滤查询列表
<picker bindchange"bindPickerChanges" value"{{selectedIndex}}"range"{{pickerArray}}"range-key"name"><view class"area-select">在线状态:<label for"">{{pickerArray[select…...

C++—— set、map、multiset、multimap的介绍及使用
目录 关联式容器 关联式容器的特点和使用场景 树形结构与哈希结构 树形结构 哈希结构 键值对 set set的介绍 set的定义方式 set的使用 multiset map map的介绍 map的定义方式 map的使用 multimap 关联式容器 C标准模板库(STL)中的关联…...

STM32 学习——1. STM32最小系统
这是一个最小系统的测试,LED灯会进行闪烁。选用PC13口,因为STM32F103C8T6 硬件开发板中,这个端口是一个LED 1. proteus8.15 原理图 2. cubemx 新建工程 3. keil 代码 while (1){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_Delay(100);…...

react实现table可拖拽表头(给react-jss样式传递参数、滚动条样式)
目录 react实现table可拖拽表头安装依赖resizableTitle / index.tsxdrapTable.tsx使用DragTable 组件滚动条样式效果 react实现table可拖拽表头 安装依赖 yarn add react-resizable yarn add react-jssresizableTitle / index.tsx import { createUseStyles } from react-js…...
如何跨过robots协议的限制爬取内容?
在讨论如何“跨过robots协议的限制爬取内容”之前,重要的是强调遵循网络礼仪和法律法规的必要性。robots协议(Robots Exclusion Standard)是网站所有者向网络爬虫(包括搜索引擎和其他自动化工具)传达其爬取意愿的一种方…...

Parasoft C++Test软件静态分析操作指南_编码规范/标准检查
系列文章目录 Parasoft CTest软件安装指南 Parasoft CTest软件静态分析操作指南_编码规范/标准检查 Parasoft CTest软件静态分析操作指南_软件质量度量 Parasoft CTest软件静态分析_自动提取静态分析数据生成文档 Parasoft CTest软件单元测试_操作指南 Parasoft CTest软件单元…...
[AIGC] CompletableFuture如何实现任务链式调用?
Java 中的 CompletableFuture 提供了多种方法来支持任务链式调用。这些方法允许你将一组操作链接在一起,形成一个任务链,每一个任务只有在上一个任务成功完成后才会被执行。现在,我们来看一下一些常用的链接任务的方法: thenAppl…...

神奇动物在哪里?斯洛文尼亚旅游之野生动物寻踪
不仅拥有优美动人的自然风光,斯洛文尼亚还以其丰富的生物多样性而闻名。得益于国家对大自然开展的保护工作,斯洛文尼亚超过三分之一的国土面积都被规划为保护区,拥有约1.5万种动物和6000种植物,其中不乏众多特有、稀有和濒危动植物…...

电商项目之有趣的支付签名算法
文章目录 1 问题背景2 思路3 代码实现 1 问题背景 在发起支付的时候,一般都需要对发送的请求参数进行加密或者签名,下文简称这个过程为“签名”。行业内比较普遍的签发算法有: (1)按支付渠道给定的字段排序进行拼接&am…...
Web开发核心
文章目录 1.http协议简介2.http协议特性3.http请求和响应协议4.最简单的Web程序5.基于flask搭建web⽹站6.浏览器开发者⼯具(重点) 1.http协议简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于 万维网(WWW:Norld W…...

【Python】【Scrapy 爬虫】理解HTML和XPath
为了从网页中抽取信息,必须对其结构有更多了解。我们快速浏览HTML、HTML的树状表示,以及在网页上选取信息的一种方式XPath。 HTML、DOM树表示以及XPath 互联网是如何工作的? 当两台电脑需要通信的时候,你必须要连接他们ÿ…...

【CTF Web】CTFShow web5 Writeup(SQL注入+PHP+位运算)
web5 1 阿呆被老板狂骂一通,决定改掉自己大意的毛病,痛下杀手,修补漏洞。 解法 注意到: <!-- flag in id 1000 -->拦截很多种字符,连 select 也不给用了。 if(preg_match("/\|\"|or|\||\-|\\\|\/|\…...
LeetCode 968.监控二叉树 (hard)
968.监控二叉树 力扣题目链接(opens new window) 给定一个二叉树,我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所有节点所需的最小摄像头数量。 贪心思路: 从下往上看,局部最…...

数理逻辑:1、预备知识
17.1 命题和联结词 命题:可以判定真假的陈述句。(则悖论,祈使句,疑问句都不是命题) 原子命题:不能被分割为更小的命题的命题 例如: 2既是素数又是偶数 可以由$p: 2 是素数,…...
14-云原生监控体系-Redis_exporter 监控 MySQL[部署Dashborad告警规则实战]
文章目录 环境准备切片集群主从哨兵1. 部署1.1. 二进制方式1.1.1. 下载二进制包1.1.2. 部署1.2. docker-compose 容器方式1.3. 配置连接&认证参数1.3.1. 连接认证参数1.3.2. 配置服务控制 systemd2. 配置到 Prometheus3 Dashboard4. 告警规则...

DOS学习-目录与文件应用操作经典案例-xcopy
新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 xcopy命令是DOS系统中一个强大的文件和目录复制工具&…...

Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人
Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人,旨在提供多领域的智能对话服务。Midjourney在不同领域中有不同的定义和应用,以下是对其中两个主要领域的介绍: Midjourney官网:https://www.midjourney.com/ 一、AI绘画工…...

v-model详解
目录 原理 作用 表单类组件封装 编辑v-model简化代码 原理 v-model本质上是一个语法糖。例如应用在输入框上,就是value属性和input属性的合写。 作用 提供数据的双向绑定。 数据变,视图跟着变:value视图变,数据跟着变input 注意&…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...