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

数据结构入门 — 顺序表详解

前言

数据结构入门 — 顺序表详解
博客主页链接:https://blog.csdn.net/m0_74014525
关注博主,后期持续更新系列文章
文章末尾有源码
*****感谢观看,希望对你有所帮助*****


文章目录

  • 前言
  • 一、顺序表
    • 1. 顺序表是什么
    • 2. 优缺点
  • 二、概念及结构
    • 1. 静态顺序表
    • 2. 动态顺序表
  • 三、顺序表接口实现(代码演示)
    • 1. 动态存储结构
    • 2. 顺序表打印
    • 3. 顺序表初始化
    • 4. 检查空间大小
    • 5. 增删查改接口
    • 6. 顺序表销毁
  • 四、所有文件代码
    • 1. Gitee链接
  • 总结


一、顺序表

1. 顺序表是什么

顺序表是连续存储的
顺序表是一种线性表的数据结构,它的数据元素按照一定次序依次存储在计算机存储器中,使用连续的存储空间来存储。顺序表中每个数据元素的位置都有一个序号,这个序号也称为元素在顺序表中的下标。顺序表的特点是:元素的逻辑顺序与物理顺序相同,支持随机访问,插入和删除元素的时间复杂度为O(n),查找元素的时间复杂度为O(1)。

2. 优缺点

优点
优点是访问速度快,因为它的元素在内存中是连续存储的,可以直接通过下标访问,而且不需要额外的空间来存储指向下一个节点的指针。
缺点
缺点是插入和删除元素的时间复杂度为O(n),因为需要移动其他元素的位置,而且不利于动态扩展容量。


二、概念及结构

元素的类型、元素的个数、数组的大小和数组的指针
顺序表的实现需要预留一段连续的存储空间来存储所有的元素,目前常见的实现方式是使用数组来实现顺序表。数组的地址是连续的,因此可以通过数组下标进行快速访问元素。为了实现顺序表,需要定义一个数据结构,包含元素的类型、元素的个数、数组的大小和数组的指针等信息。

1. 静态顺序表

静态顺序表是一种使用连续存储空间实现的线性表结构,其特点是在创建表时就需要预先分配好固定长度的存储空间,表长也就固定了下来,不能动态扩展或缩小。

在静态顺序表中,数据元素按照顺序依次存放,每个元素都占用相同的存储空间,而且元素在内存中的地址也是连续的。
在这里插入图片描述

2. 动态顺序表

动态顺序表是一种线性表的实现方式,它在静态顺序表的基础上,将存储空间由固定长度改为动态分配。

当动态顺序表中存放的元素个数达到当前存储空间的上限时,可以重新申请更大的空间来存放更多的元素,因此动态顺序表的长度是可变的。动态顺序表的实现通常采用数组形式,通过realloc函数来动态分配空间。

在这里插入图片描述


三、顺序表接口实现(代码演示)

1. 动态存储结构

即定义顺序表的结构。由动态开辟的数组、有效数据个数和容量空间的大小组成

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

2. 顺序表打印

使用循环,将顺序表遍历一遍,进行打印

//打印顺序表
void SLPrint(SL* pc)
{assert(pc);int i = 0;for (i = 0; i < pc->size; i++){printf("%d ", pc->a[i]);}printf("\n");
}

3. 顺序表初始化

在顺便表初始化时,先用malloc开辟4个空间,如果开启失败报错并返回

//初始化顺序表
void SLInit(SL *pc)
{assert(pc);//开启内存  pc->a=(SLDataType*)malloc(sizeof(SLDataType) * 4);//检查是否开辟成功if (pc->a==NULL){perror("SLInit");//return;exit(-1);}pc->capacity = 4;pc->size = 0;
}

4. 检查空间大小

检查空间,当顺序表内的数据等于初始化开辟的空间时,再开辟4个空间(用realloc开辟乘2的空间)

//检查内存容量
void SLCheckCapacity(SL* pc)
{assert(pc);if (pc->size == pc->capacity){SLDataType*tem = (SLDataType*)realloc(pc->a, sizeof(SLDataType)*2*pc->capacity);  //要乘以2if (tem == NULL){perror("SLCheckCapacity");exit(-1);}pc->a = tem;pc->capacity *= 2;}
}

5. 增删查改接口

以增删查改顺序依次编排
头插:
头插,即在顺序表头部进行插入数值,在SLCheckCapacity检查空间是否充足后,进行插入数值

//头插
void SLPushFront(SL* pc,SLDataType x)
{assert(pc);SLCheckCapacity(pc);int end = pc->size - 1;while (end >=0){pc->a[end + 1] = pc->a[end];--end;}pc->a[0] = x;pc->size++;
}

尾插:
尾插,即找到顺序表的尾,下标为pc->size的位置插入数值

//尾插
void SLPushBack(SL* pc, SLDataType x)
{assert(pc);SLCheckCapacity(pc);pc->a[pc->size] = x;pc->size++;
}

头删:
头删,将后面的数值依次向前覆盖。覆盖时要注意顺序,将在前的先覆盖,防止数组丢失,然后将顺序表的size(数据个数减一)

//头删
void SLPopFront(SL* pc)
{assert(pc);int start = 1;while (start < pc->size){pc->a[start] = pc->a[start + 1];++start;}pc->size--;
}

尾删:
尾删,即将有效数据减一,直接将pc所指向的size减一

//尾删
void SLPopBack(SL* pc)
{assert(pc->size > 0);pc->size--;
}

查找:
查找方法有很多种,这里使用暴力查找,将顺序表遍历一遍,找到要找的元素并返回下标

//查找数字位置
int SLFind(SL* pc, SLDataType x)
{int i = 0;for (i = 0; i < pc->size; i++){if (pc->a[i] == x){return i;}}return -1;
}

指定位置插入
这里配合查找函数使用,找到要找的数值的下标,进入下列函数,将pos之后的值依次下向后移动,在pos位置插入数值

// 在pos位置插入x
void SLInsert(SL* pc, int pos, SLDataType x)
{assert(pc);assert(pos >= 0 && pos <= pc->size);SLCheckCapacity(pc);int end = pc->size - 1;while (end >= pos){pc->a[end + 1] = pc->a[end];--end;}pc->a[pos] = x;pc->size++;}

指定位置删除
这里配合查找函数使用,找到要找的数值的下标,进入下列函数,将pos位置后的数值依次向前覆盖

// 删除pos位置的值
void SLErase(SL* pc, int pos)
{assert(pc);assert(pos >= 0 && pos < pc->size);int start = pos+ 1;while (start < pc->size){pc->a[start - 1] = pc->a[start];++start;}pc->size--;
}

更改指定位置
这里配合查找函数使用,找到要找的数值的下标,进入下列函数,将pos位置的值进行修改

//更改制定位置的数字
void SLModify(SL* pc, int pos, SLDataType x)
{assert(pc);assert(pos >= 0 && pos < pc->size);pc->a[pos] = x;}

6. 顺序表销毁

顺序表进行销毁,将开辟的数值空间进行释放,并置为空(NULL)将空间和数据个数置为0 ,这样顺序表就销毁完成


//销毁释放内存
void SLDestroy(SL* pc)
{assert(pc);free(pc->a);pc->a=NULL;pc->capacity = 0;pc->size=0;
}

四、所有文件代码

1. Gitee链接

***查看所有代码***
点击右边蓝色文字 DuckBro Gitee 代码仓库


总结

顺序表是一种线性表,它的重点是:

  1. 物理结构:顺序表的数据元素在内存中是连续存放的,即使用一段连续的存储空间来存储线性表的元素。

  2. 逻辑结构:顺序表是一种线性表,它的元素在逻辑上是依次排列的。

  3. 数据操作:顺序表支持基本的数据操作,包括插入、删除、查找等操作。其中,插入和删除操作需要移动大量元素,时间复杂度较高,而查找操作可以通过使用二分查找等算法来提高效率。

  4. 容量管理:顺序表的容量是由数组的长度来决定的。如果数组长度不够,顺序表需要进行扩容操作,如果数组长度过长,会浪费内存空间。

  5. 性能特点:由于顺序表的数据元素在内存中是连续存放的,所以顺序表具有快速的随机访问能力,但插入、删除操作较为耗时。因此,适合于需要随机访问元素,但不频繁进行插入、删除操作的场景。顺序表


如这篇博客对大家有帮助的话,希望 三连 支持一下 !!! 如果有错误感谢大佬的斧正 如有 其他见解发到评论区,一起学习 一起进步。

相关文章:

数据结构入门 — 顺序表详解

前言 数据结构入门 — 顺序表详解 博客主页链接&#xff1a;https://blog.csdn.net/m0_74014525 关注博主&#xff0c;后期持续更新系列文章 文章末尾有源码 *****感谢观看&#xff0c;希望对你有所帮助***** 文章目录 前言一、顺序表1. 顺序表是什么2. 优缺点 二、概念及结构…...

SimpleCG绘图函数(9)--绘制各种线条

一、所有线段函数概述 可填充图形绘制函数都介绍完了&#xff0c;还有一些特殊线条的绘制将在本篇进行讲解。所有特殊线条函数如下所示&#xff0c;其中还有一个区域填充函数floodfill比较特殊&#xff0c;是配合线条函数使用的&#xff1a; //绘制一系列折线段 //折线段以一组…...

RISCV 6 RISC-V加载存储指令

RISCV 6 RISC-V加载存储指令 1 RV32I Load and Store Instructions1.1 LOAD instructions1.1.1 加载指令的指令格式1.1.2 加载指令在使用时需要注意的点 1.2 STORE instructions1.2.1 存储指令的指令格式1.2.2 存储指令在使用时需要注意的点 2 RV64 Load and Store Instruction…...

木叶飞舞之【机器人ROS2】篇章_第二节、turtlebot3安装

没有真实小车的情况下&#xff0c;利用gazebo的仿真&#xff0c;操作小乌龟来学习ros2。废话不多说&#xff0c;直接上命令。 Install Gazebo sudo apt install ros-humble-gazebo-*Install Cartographer 假如前一节未安装源码版本的cartographer&#xff0c;那就安装apt版本…...

【论文阅读】自动驾驶安全的研究现状与挑战

文章目录 摘要1.引言1.1.自动驾驶安全1.2.攻击面1.3.内容和路线图 2.自动驾驶技术2.1.组成2.2.技术 3.传感器安全3.1.照相机3.2.GNSS&#xff08;全球导航系统&#xff09;/IMU&#xff08;惯性测量单元&#xff09;3.3.超声波传感器3.4.毫米波雷达3.5.激光雷达3.6.多传感器交叉…...

标签打印小工具 选择图片打印,按实际尺寸打印。可旋转图片

您可以尝试使用以下标签打印工具&#xff1a; 柯尼卡美能达标签打印机&#xff1a;功能齐全、易于使用的打印机&#xff0c;支持各种标签尺寸和类型。 赛门铁克标签打印机&#xff1a;高速打印、可靠性强的打印机&#xff0c;支持多种操作系统和软件。 齐柏林标签打印机&…...

什么是深拷贝和浅拷贝?

面试回答 在计算机内存中&#xff0c;每个对象都有一个地址&#xff0c;这个地址指向对象在内存中存储的位置。当我们使用变量引用一个对象时&#xff0c;实际上是将该对象的地址赋值给变量。因此&#xff0c;如果我们将一个对象复制到另一个变量中国&#xff0c;实际上是将对象…...

安装docker服务及docker基本操作

一、docker安装&#xff08;yum安装&#xff09; 基于centos7 1.添加docker-ce 源信息 安装依赖包&#xff08;yum-utils 提供了 yum-config-manager &#xff0c;并且 device mapper 存储驱动程序需要device-mapper-persistent-data 和 lvm2&#xff09; yum install yum-…...

【项目经验】:项目中下拉框数据太多造成页面卡顿(二)

一.项目需求 下拉框下拉列表数据是由后端返回的&#xff0c;而且他会变化&#xff0c;所以数据不是写死的而且数据量大。上一篇博客http://t.csdn.cn/sSNTa我们是用的数据懒加载的方式&#xff0c;这次我们使用远程搜索的方式解决这个问题。 二.用到的组件方法介绍 filterabl…...

Prompt本质解密及Evaluation实战(一)

一、基于evaluation的prompt使用解析 基于大模型的应用评估与传统应用程序的评估不太一样&#xff0c;特别是基于GPT系列或者生成式语言模型&#xff0c;因为模型生成的内容与传统意义上所说的内容或者标签不太一样。 以下是借用了ChatGPT官方的evaluation指南提出的对结果的具…...

linux 在系统已有python2版本下安装python3

方法一&#xff1a;使用包管理器安装 更新包索引&#xff1a; sudo apt update 安装Python3&#xff1a; sudo apt install python3 安装Python3的pip&#xff08;如果你需要&#xff09;&#xff1a; sudo apt install python3-pip 验证Python 2和3的安装&#xff1a; pyt…...

IO多路转接 ——— select、poll、epoll

select初识 select是系统提供的一个多路转接接口。 select系统调用可以让我们的程序同时监视多个文件描述符的上的事件是否就绪。 select的核心工作就是等&#xff0c;当监视的多个文件描述符中有一个或多个事件就绪时&#xff0c;select才会成功返回并将对应文件描述符的就绪…...

FPGA原理与结构——FIFO IP核原理学习

一、FIFO概述 1、FIFO的定义 FIFO是英文First-In-First-Out的缩写&#xff0c;是一种先入先出的数据缓冲器&#xff0c;与一般的存储器的区别在于没有地址线&#xff0c; 使用起来简单&#xff0c;缺点是只能顺序读写数据&#xff0c;其数据地址由内部读写指针自动加1完成&…...

【Linux操作系统】Linux中的信号回收:管理子进程的关键步骤

在Linux中&#xff0c;我们可以通过捕获SIGCHLD信号来实现对子进程的回收。当一个子进程终止时&#xff0c;内核会向其父进程发送SIGCHLD信号。父进程可以通过注册信号处理函数&#xff0c;并在处理函数中调用wait()或waitpid()函数来回收已终止的子进程。 文章目录 借助信号捕…...

Spark大数据分析与实战笔记(第一章 Scala语言基础-1)

文章目录 章节概要1.1 初识Scala1.1.1 Scala的概述1.1.2 Scala的下载安装1.1.3 在IDEA开发工具中下载安装Scala插件1.1.4 开发第一个Scala程序 章节概要 Spark是专为大规模数据处理而设计的快速通用的计算引擎&#xff0c;它是由Scala语言开发实现的&#xff0c;关于大数据技术…...

R语言03-R语言中的矩阵

概念 在R语言中&#xff0c;矩阵&#xff08;Matrix&#xff09;是一个二维的数据结构&#xff0c;由行和列组成&#xff0c;其中所有元素必须具有相同的数据类型。矩阵可以用于存储数值型数据&#xff0c;常用于线性代数运算、统计计算以及数据处理等领域。 代码示例 # 创建…...

“深入理解JVM:探索Java虚拟机的工作原理与优化技巧“

标题&#xff1a;深入理解JVM&#xff1a;探索Java虚拟机的工作原理与优化技巧 摘要&#xff1a;本文将深入探索Java虚拟机&#xff08;JVM&#xff09;的工作原理及优化技巧。我们将介绍JVM的架构和组成部分&#xff0c;解释JVM是如何将Java字节码转换为可执行代码的。我们还…...

SQL注入原理

SQL、SQL注入是什么&#xff1f; 结构化查询语言(Structured Query Language&#xff0c;SQL)&#xff0c;是一种特殊的编程语言&#xff0c;用于数据库的标准数据查询。1986 年10 月美国国家标准协会对SQL 进行了规范后&#xff0c;以此作为关系型数据库系统的标准语言。1987 …...

PIL.Image和base64,格式互转

将PIL.Image转base64 ##PIL转base64 import base64 from io import BytesIOdef pil_base64(image):img_buffer BytesIO()image.save(img_buffer, formatJPEG)byte_data img_buffer.getvalue()base64_str base64.b64encode(byte_data)return base64_str将base64转PIL.Image …...

vue父子组件传值(v-model)

父组件使用v-model传值给子组件 <template><!-- 按钮 --> <el-button click"addMenu(new)">打开弹框</el-button><!-- 自定义组件,下面这两种写法都可以&#x1f447; --> <MediaDialog :name"name" v-model:visible&qu…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的&#xff0c;需要先安…...