【数据结构】顺序表 | 详细讲解
在计算机中主要有两种基本的存储结构用于存放线性表:顺序存储结构和链式存储结构。本篇文章介绍采用顺序存储的结构实现线性表的存储。
顺序存储定义
线性表的顺序存储结构,指的是一段地址连续的存储单元依次存储链性表的数据元素。
线性表的(,
……
)的顺序存储示意图如下:

就比如说,在大学期间,我们同宿舍的有一个同学,人特别老实、热心,我们时常会让他帮我们去图书馆占座,他总是答应,你想想,我们一个宿舍连他共有九个人,这其实明摆着是欺负人的事。他每次一吃完早饭就冲去图书馆,挑一个好地儿,把他的书包里的书,一本一本地按座位放好,若书包里的书不够,他会把他的饭盒、水杯、水笔都用上,长长一排,九个座位硬是被他给占了,后来有一次因占座的事情弄得差点都要打架。
顺序存储方式
线性表的顺序存储结构,说白了,和刚刚的例子一样,就是在内存中找了块地,通过占位的形式,把一定的内存空间给占了,然后把相同数据类型的数据元素依次存放在这块空地中。既然线性表的每个数据元素的类型都相同,所以可以用C语言(其他语言也相同)的一维数组来实现顺序存储结构,即把第一个数据元素存到数组下标为0的位置中,接着把线性表相邻的元素存储在数组中相邻的位置。
线性表中,我们估算这个线性表的最大存储容量,建立一个数组,数组的长度就是这个最大存储容量。随着数据的插入,我们线性表的长度开始变大,不过线性表的当前长度不能超过存储容量,即数组的长度。
数据长度与线性表长度区别
注意哦,这里有两个概念“数据的长度”和“线性表的长度”需要区分一下。
数组的长度是存放线性表的存储空间的长度,在静态分配的一维数组中,存储分配后这个量是一般不变的。但在动态分配的一维空间中,是可以实现动态分配数组。
线性表的长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量是变化的。
地址计算方法
由于我们数数都是从1开始数的,线性表的定义也不能免俗,起始也是1,可C语言中的数组是从0开始的,于是线性表的第i个元素是要存储在数组下标为i-1的位置,即数据元素的序号和存放它的数组下标之间存在对应的关系。

用数组存储顺序表意味着要分配固定长度的数组空间,由于线性表中可以进行插入和删除操作,因此分配的数组空间要大于等于当前线性表的长度。
存储器中的每一个存储单元都有自己的编号,这个编号称为地址。在前一个地址确定好之后,那么后面的位置都是可以计算的。由于每个数据元素,不管它是整形、实型还是字符型, 它都是需要占用一定的存储单元空间的。假设占用的是c个存储单元,那么线性表中第i+1个数据元素的存储位置和第i个数据元素的存储位置满足下列关系(LOC表示获得存储位置的函数)。
LOC(
)=LOC(
)+c
所以对于第i个数据元素的存储位置可以由
推算得出:
LOC(
)=LOC(
)+(i-1)*c

地址计算公式,可以随时算出线性表中任意位置的地址,不管它是第一个还是最后一个,都是相同的时间。那么我们对每个线性表位置的存入或者取出数据,对于计算机来说都是相等的时间,也就是一个常数,因此用我们算法中学到的时间复杂度的概念来说,它的存取时间性能为O(1)。具有这一特点的存储结构称为随机存取结构。
顺序表的代码实现分析
顺序表是用一段物理地址连续的存储单元依次存储数据元素的数据结构,一般情况下采用数组存储。在数组上完成数据的增删改查。
顺序表一般可以分为:
- 静态顺序表:使用定长数组存储元素。
- 动态顺序表:使用动态开辟的数组存储。
//顺序表的静态存储
#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--;
}
相关文章:
【数据结构】顺序表 | 详细讲解
在计算机中主要有两种基本的存储结构用于存放线性表:顺序存储结构和链式存储结构。本篇文章介绍采用顺序存储的结构实现线性表的存储。 顺序存储定义 线性表的顺序存储结构,指的是一段地址连续的存储单元依次存储链性表的数据元素。 线性表的…...
100天精通风控建模(原理+Python实现)——第1天:什么是风控建模?
风控模型已在各大银行和公司都实际运用于业务,用于营销和风险控制等。本文以视频的形式阐述什么是风控建模,并提供风控建模原理和Python实现文章清单。首先了解什么是风控建模? 下文梳理风控模型搭建的原理和Python实现,按顺序做成清单的形式,点击即可进入相应文章链接。方…...
HTML转义字符
HTML,XML文件中存在部分字符作为标志字符无法作为文本内容使用,如< >,如果想在文本中输出,可使用转义字符。 < 的转义字符为 " < " > 的转义字符为 " > " <TextView.... ....android:t…...
【STM32】
STM32 1 CMSIS1.1 概述1.2 CMSIS 应用程序文件描述 2 库2.1 简介2.2 标准外设库(standrd Peripheral Libraries)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盘打不开,可按下图,设置:winR→gpedit.msc;配置“管理模板”→“系统”→“可移动存储访问”→“所有可移动存储类”。 然后,选择“未配置”,如下图...
SpringCloud 微服务全栈体系(十三)
第十一章 分布式搜索引擎 elasticsearch 二、索引库操作 索引库就类似数据库表,mapping 映射就类似表的结构。 我们要向 es 中存储数据,必须先创建“库”和“表”。 1. mapping 映射属性 mapping 是对索引库中文档的约束,常见的 mapping …...
ROC 曲线详解
前言 ROC 曲线是一种坐标图式的分析工具,是由二战中的电子和雷达工程师发明的,发明之初是用来侦测敌军飞机、船舰,后来被应用于医学、生物学、犯罪心理学。 如今,ROC 曲线已经被广泛应用于机器学习领域的模型评估,说…...
113.路径总和II
原题链接:113.路径总和II 需复刷 思路: 跟112.路径总和不同,该题是要你找出所有相同的路径,那么此时就要注意存储,递归和回溯了。 全代码: class Solution { public:vector<vector<int>> re…...
【Linux】WSL安装Kali及基本操作
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍WSL安装Kali及基本操作。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路…...
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 令牌,可用于访问所有 admin API,通过 2.x 版本中添加的参数导致远程执行 LUA 代码。 漏洞环境及利用 启动docker环境 访问9080端口 通过 admin api…...
Clickhouse学习笔记(3)—— Clickhouse表引擎
前言: 有关Clickhouse的前置知识详见: 1.ClickHouse的安装启动_clickhouse后台启动_THE WHY的博客-CSDN博客 2.ClickHouse目录结构_clickhouse 目录结构-CSDN博客 Cickhouse创建表时必须指定表引擎 表引擎(即表的类型)决定了&…...
WebSocket是什么以及其与HTTP的区别
新钛云服已累计为您分享774篇技术干货 HTTP协议 HTTP是单向的,客户端发送请求,服务器发送响应。举个例子,当用户向服务器发送请求时,该请求采用HTTP或HTTPS的形式,在接收到请求后,服务器将响应发送给客户端…...
Flutter 实战:构建跨平台应用
文章目录 一、简介二、开发环境搭建三、实战案例:开发一个简单的天气应用1. 项目创建2. 界面设计3. 数据获取4. 实现数据获取和处理5. 界面展示6. 添加动态效果和交互7. 添加网络错误处理8. 添加刷新功能9. 添加定位功能10. 添加通知功能11. 添加数据持久化功能 《F…...
Python中68个内置函数的使用与归类
前言 在Python解释器中内置的、可以直接使用的函数。这些函数不需要额外的导入或安装,可以直接在Python代码中调用。Python内置函数包括了很多常用的功能,比如对数据类型的操作、数学运算、字符串处理、文件操作等。一些常见的内置函数包括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的射频和高电压电路设计
标题:Facilitation of GaN-Based RF- and HV-Circuit Designs Using MVS-GaN HEMT Compact Model 来源:IEEE TRANSACTIONS ON ELECTRON DEVICES(19年) 摘要—本文阐述了基于物理的紧凑器件模型在研究器件行为细微差异对电路和系统…...
Android13分享热点设置安全性为wpa3
Android13分享热点设置安全性为wpa3 文章目录 Android13分享热点设置安全性为wpa3一、前言热点WPA3加密类型是需要底层硬件支持的。Wifi WPA3 和 热点 WPA3 是不一样的分享初衷 二、代码分析1、应用代码中热点设置WPA3 加密格式报错部分日志信息: 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发展介绍,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…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
