当前位置: 首页 > news >正文

【数据结构】顺序表 | 详细讲解

在计算机中主要有两种基本的存储结构用于存放线性表:顺序存储结构和链式存储结构。本篇文章介绍采用顺序存储的结构实现线性表的存储。

顺序存储定义

线性表的顺序存储结构,指的是一段地址连续的存储单元依次存储链性表的数据元素。

线性表的(^{a_1{}}^{a_2{}}……^{a_n{}})的顺序存储示意图如下:

就比如说,在大学期间,我们同宿舍的有一个同学,人特别老实、热心,我们时常会让他帮我们去图书馆占座,他总是答应,你想想,我们一个宿舍连他共有九个人,这其实明摆着是欺负人的事。他每次一吃完早饭就冲去图书馆,挑一个好地儿,把他的书包里的书,一本一本地按座位放好,若书包里的书不够,他会把他的饭盒、水杯、水笔都用上,长长一排,九个座位硬是被他给占了,后来有一次因占座的事情弄得差点都要打架。

顺序存储方式

线性表的顺序存储结构,说白了,和刚刚的例子一样,就是在内存中找了块地,通过占位的形式,把一定的内存空间给占了,然后把相同数据类型的数据元素依次存放在这块空地中。既然线性表的每个数据元素的类型都相同,所以可以用C语言(其他语言也相同)的一维数组来实现顺序存储结构,即把第一个数据元素存到数组下标为0的位置中,接着把线性表相邻的元素存储在数组中相邻的位置。

线性表中,我们估算这个线性表的最大存储容量,建立一个数组,数组的长度就是这个最大存储容量。随着数据的插入,我们线性表的长度开始变大,不过线性表的当前长度不能超过存储容量,即数组的长度

数据长度与线性表长度区别

注意哦,这里有两个概念“数据的长度”和“线性表的长度”需要区分一下。

数组的长度是存放线性表的存储空间的长度,在静态分配的一维数组中,存储分配后这个量是一般不变的。但在动态分配的一维空间中,是可以实现动态分配数组。

线性表的长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量是变化的。

地址计算方法

由于我们数数都是从1开始数的,线性表的定义也不能免俗,起始也是1,可C语言中的数组是从0开始的,于是线性表的第i个元素是要存储在数组下标为i-1的位置,即数据元素的序号和存放它的数组下标之间存在对应的关系。

用数组存储顺序表意味着要分配固定长度的数组空间,由于线性表中可以进行插入和删除操作,因此分配的数组空间要大于等于当前线性表的长度。

存储器中的每一个存储单元都有自己的编号,这个编号称为地址。在前一个地址确定好之后,那么后面的位置都是可以计算的。由于每个数据元素,不管它是整形、实型还是字符型, 它都是需要占用一定的存储单元空间的。假设占用的是c个存储单元,那么线性表中第i+1个数据元素的存储位置和第i个数据元素的存储位置满足下列关系(LOC表示获得存储位置的函数)。

LOC(a_{i+1})=LOC(a_{i})+c

所以对于第i个数据元素a_{i}的存储位置可以由a_{1}推算得出:

LOC(a_{i})=LOC(a_{i})+(i-1)*c

地址计算公式,可以随时算出线性表中任意位置的地址,不管它是第一个还是最后一个,都是相同的时间。那么我们对每个线性表位置的存入或者取出数据,对于计算机来说都是相等的时间,也就是一个常数,因此用我们算法中学到的时间复杂度的概念来说,它的存取时间性能为O(1)。具有这一特点的存储结构称为随机存取结构。

顺序表的代码实现分析

顺序表是用一段物理地址连续的存储单元依次存储数据元素的数据结构,一般情况下采用数组存储。在数组上完成数据的增删改查。

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。
  2. 动态顺序表:使用动态开辟的数组存储。
//顺序表的静态存储
#define N 7
typedef int SLDataType;
typedef struct SeqList
{SLDataType array[N];//定长数组size_t size;        //有效数据的个数
}SL;//顺序表的动态存储
typedef int SLDataType;
typedef struct SeqList
{SLDataType* array; //指向动态开辟的数组size_t size;//有效数据个数size_t capacity;//容量空间的大小
}SL;

其实在平时以及以后的工作环境中,静态存储实践很少,因为不知道需要多少内存空间,N给大了不够用,N给小了浪费。静态顺序表只适合用于确定知道需要存多少数据的场景。所以在现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

顺序表的结构代码

typedef int SLDataType;
//顺序表的动态存储
typedef struct SeqList
{SLDataType* a; //指向动态开辟的数组size_t size;//有效数据个数size_t capacity;//容量空间的大小
}SL;

顺序表的初始化

在这个顺序表中有一个a数组,一个size是指有效数据的个数,一个capacity是容量空间的大小。对于size而言,size是有效数据的个数,而看作下标的话,那便是最后一个元素的下一个下标

在进行初始化是,要对数组以及顺序表结构体中的size以及capacity都进行初始化。

void SLInit(SL* psl)
{psl->a = NULL;psl->size = 0;psl->capacity = 0;
}

顺序表的销毁

起初,顺序表是一个空表,但是经过了一系列的增删改查之后就会存储一些数据,之后我们在销毁这个链表时,这个链表就是有内容的,所以在这里我们需要注意的是,销毁时需要断言一下这个顺序表是否为空,如果是空表的话,那还销毁什么。其次在销毁时,思路也很简单,无非就是让这个顺序表的几个变量都变为0。

void SLDestory(SL* psl)
{assert(psl);if (psl->a != NULL){free(psl->a);psl->a = NULL;psl->size = 0;psl->capacity = 0;}
}

顺序表的遍历打印

遍历打印的思路极其类似于数组的打印,利用下标即可。下标是从零开始的,且size是有效数据的个数即最后一个数据的下一个下标,所以这里的循环条件就是i<size。

void SeqListPrint(SL* psl)
{assert(psl);int i = 0;for (i = 0; i < psl->size; i++){printf("%d ", psl->a[i]);}printf("\n");
}

顺序表的扩容 

因为在刚刚开始的时候,我们初始化size以及capacity都为0,所以为了防止每次扩容都是0,所以利用三目操作符来进行判断,如果这个capacity为0的话,那么就直接扩容4字节,其他的都是扩容它的两倍。

void SLCheckCapacity(SL* psl)
{assert(psl);int Newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(psl->a, Newcapacity * sizeof(SLDataType));if (tmp == NULL){perror("realloc fail\n");}psl->a = tmp;psl->capacity = Newcapacity;
}

顺序表的尾插

在添加数据时,不论是前插后插还是在指定位置插入,我们都需要为其判断是否有足够的空间,也就是判断是否需要扩容。扩容之后将数据插入顺序表中。

void SeqListPushBack(SL* psl, SLDataType x)
{assert(psl);SLCheckCapacity(psl);psl->a[psl->size - 1] = x;psl->size++;
}

这里注意一下,在尾插之后需要将size++。 

顺序表的头插

顺序表的头插相比较尾插就较难一些,因为需要将所有的数据都向后挪动一位。所以得再借助一个指针用来遍历。

void SeqListPushFront(SL* psl, SLDataType x)
{assert(psl);SLCheckCapacity(psl);int end = psl->size - 1;while (end >= 0){psl->a[end+1] = psl->a[end];end--;}psl->a[0] = x;psl->size++;
}

顺序表的尾删

尾删还是比较容易的,无非就是将size--,但是这里还要断言一下确保size是大于零的。

void SeqListPopBack(SL* psl)
{assert(psl);assert(psl->size > 0);psl->size--;
}

顺序表的头删

如果想要头删的那话,就是将后面的元素给覆盖到前一个,从前往后开始。

void SeqListPopFront(SL* psl)
{assert(psl);assert(psl->size > 0);int begin = 1;while (begin <= psl->size - 1){psl->a[begin - 1] = psl->a[begin];begin++;}psl->size--;
}

顺序表的查找

顺序表查找,在这个顺序表中是否有这个数组。其实这个也就是遍历,很简单利用下标。

int SeqListFind(SL* psl, SLDataType x)
{int i = 0;for (int i = 0; i < psl->size; i++){if (psl->a[i] == x){return i;}}
}

顺序表在pos位置插入x的数

这里我们需要断言一下这个是否为有效位置。 

void SeqListInsert(SL* psl, int pos, SLDataType x)
{assert(psl);assert(pos >= 0 && pos <= psl->size);SLCheckCapacity(psl);int end = psl->size - 1;while (end >= pos){psl->a[end + 1] = psl->a[end];end--;}psl->a[pos] = x;psl->size++;
}

顺序表删除pos位置上的值

void SeqListErase(SL* psl, int pos)
{assert(psl);assert(pos >= 0 && pos <= psl->size);int begin = pos + 1;while (begin <= psl->size - 1){psl->a[begin - 1] = psl->a[begin];begin++;}psl->size--;
}

相关文章:

【数据结构】顺序表 | 详细讲解

在计算机中主要有两种基本的存储结构用于存放线性表&#xff1a;顺序存储结构和链式存储结构。本篇文章介绍采用顺序存储的结构实现线性表的存储。 顺序存储定义 线性表的顺序存储结构&#xff0c;指的是一段地址连续的存储单元依次存储链性表的数据元素。 线性表的&#xf…...

100天精通风控建模(原理+Python实现)——第1天:什么是风控建模?

风控模型已在各大银行和公司都实际运用于业务,用于营销和风险控制等。本文以视频的形式阐述什么是风控建模,并提供风控建模原理和Python实现文章清单。首先了解什么是风控建模? 下文梳理风控模型搭建的原理和Python实现,按顺序做成清单的形式,点击即可进入相应文章链接。方…...

HTML转义字符

HTML&#xff0c;XML文件中存在部分字符作为标志字符无法作为文本内容使用&#xff0c;如< >&#xff0c;如果想在文本中输出&#xff0c;可使用转义字符。 < 的转义字符为 " < " > 的转义字符为 " > " <TextView.... ....android:t…...

【STM32】

STM32 1 CMSIS1.1 概述1.2 CMSIS 应用程序文件描述 2 库2.1 简介2.2 标准外设库&#xff08;standrd Peripheral Libraries&#xff09;2.3 HAL 库2.3.1 目录结构2.3.2 HAL库API函数和变量的命名规则2.3.3 HAL库对寄存器位操作的相关宏定义2.3.4 HAL库回调函数2.3.5 HAL使用注意…...

U盘不可以访问的维护

u盘打不开&#xff0c;可按下图&#xff0c;设置&#xff1a;winR→gpedit.msc&#xff1b;配置“管理模板”→“系统”→“可移动存储访问”→“所有可移动存储类”。 然后&#xff0c;选择“未配置”&#xff0c;如下图...

SpringCloud 微服务全栈体系(十三)

第十一章 分布式搜索引擎 elasticsearch 二、索引库操作 索引库就类似数据库表&#xff0c;mapping 映射就类似表的结构。 我们要向 es 中存储数据&#xff0c;必须先创建“库”和“表”。 1. mapping 映射属性 mapping 是对索引库中文档的约束&#xff0c;常见的 mapping …...

ROC 曲线详解

前言 ROC 曲线是一种坐标图式的分析工具&#xff0c;是由二战中的电子和雷达工程师发明的&#xff0c;发明之初是用来侦测敌军飞机、船舰&#xff0c;后来被应用于医学、生物学、犯罪心理学。 如今&#xff0c;ROC 曲线已经被广泛应用于机器学习领域的模型评估&#xff0c;说…...

113.路径总和II

原题链接&#xff1a;113.路径总和II 需复刷 思路&#xff1a; 跟112.路径总和不同&#xff0c;该题是要你找出所有相同的路径&#xff0c;那么此时就要注意存储&#xff0c;递归和回溯了。 全代码&#xff1a; class Solution { public:vector<vector<int>> re…...

【Linux】WSL安装Kali及基本操作

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍WSL安装Kali及基本操作。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路…...

Linux基础开发工具之调试器gdb

文章目录 1.编译成的可调试的debug版本1.1gcc test.c -o testdebug -g1.2readelf -S testdebug | grep -i debug 2.调试指令2.0quit退出2.1list/l/l 数字: 显示代码2.2run/r运行2.3断点相关1. break num/b num: 设置2. info b: 查看3. d index: 删除4. n: F10逐过程5. p 变量名…...

Apache APISIX 的 Admin API 默认访问令牌漏洞(CVE-2020-13945)漏洞复现

漏洞描述 Apache APISIX 是一个动态、实时、高性能的 API 网关。Apache APISIX 有一个默认的内置 API 令牌&#xff0c;可用于访问所有 admin API&#xff0c;通过 2.x 版本中添加的参数导致远程执行 LUA 代码。 漏洞环境及利用 启动docker环境 访问9080端口 通过 admin api…...

Clickhouse学习笔记(3)—— Clickhouse表引擎

前言&#xff1a; 有关Clickhouse的前置知识详见&#xff1a; 1.ClickHouse的安装启动_clickhouse后台启动_THE WHY的博客-CSDN博客 2.ClickHouse目录结构_clickhouse 目录结构-CSDN博客 Cickhouse创建表时必须指定表引擎 表引擎&#xff08;即表的类型&#xff09;决定了&…...

WebSocket是什么以及其与HTTP的区别

新钛云服已累计为您分享774篇技术干货 HTTP协议 HTTP是单向的&#xff0c;客户端发送请求&#xff0c;服务器发送响应。举个例子&#xff0c;当用户向服务器发送请求时&#xff0c;该请求采用HTTP或HTTPS的形式&#xff0c;在接收到请求后&#xff0c;服务器将响应发送给客户端…...

Flutter 实战:构建跨平台应用

文章目录 一、简介二、开发环境搭建三、实战案例&#xff1a;开发一个简单的天气应用1. 项目创建2. 界面设计3. 数据获取4. 实现数据获取和处理5. 界面展示6. 添加动态效果和交互7. 添加网络错误处理8. 添加刷新功能9. 添加定位功能10. 添加通知功能11. 添加数据持久化功能 《F…...

Python中68个内置函数的使用与归类

前言 在Python解释器中内置的、可以直接使用的函数。这些函数不需要额外的导入或安装&#xff0c;可以直接在Python代码中调用。Python内置函数包括了很多常用的功能&#xff0c;比如对数据类型的操作、数学运算、字符串处理、文件操作等。一些常见的内置函数包括print()、len…...

AGV無人搬送車控制系统Pytorn

import tkinter as tk import Main import monitoring # メインウィンドウを作成 root tk.Tk() root.title("AGV無人搬送車控制系统 ver1.0.0") # ウィンドウサイズを固定 root.geometry("501x340") root.resizable(False, False) # サイズ変更を…...

使用MVS-GaN HEMT紧凑模型促进基于GaN的射频和高电压电路设计

标题&#xff1a;Facilitation of GaN-Based RF- and HV-Circuit Designs Using MVS-GaN HEMT Compact Model 来源&#xff1a;IEEE TRANSACTIONS ON ELECTRON DEVICES&#xff08;19年&#xff09; 摘要—本文阐述了基于物理的紧凑器件模型在研究器件行为细微差异对电路和系统…...

Android13分享热点设置安全性为wpa3

Android13分享热点设置安全性为wpa3 文章目录 Android13分享热点设置安全性为wpa3一、前言热点WPA3加密类型是需要底层硬件支持的。Wifi WPA3 和 热点 WPA3 是不一样的分享初衷 二、代码分析1、应用代码中热点设置WPA3 加密格式报错部分日志信息&#xff1a; 2、系统代码分析&a…...

2023-11-12 LeetCode每日一题(Range 模块)

2023-03-29每日一题 一、题目编号 715. Range 模块二、题目链接 点击跳转到题目位置 三、题目描述 Range模块是跟踪数字范围的模块。设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们。 半开区间 [left, right) 表示所有 left < x < right 的实数 x 。 实…...

【六袆 - Framework】Angular-framework;前端框架Angular发展的由来0001;

Angular发展介绍&#xff0c;Angular17新特性 官方文档Angular框架发展的由来何为结构化、模块化 Angular17新特性 English unit Embarking on the journey of deep technical learning requires a well-structured approach, applicable to any programming language. The key…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...