数据结构:顺序表(Sequence List)及其实现
什么是顺序表?
顺序表是一种最简单的数据结构,它就像一排连续的小房子,每个房子里都住着一个数据元素。这些房子是按顺序排列的,每个房子都有一个门牌号(下标),我们可以通过门牌号快速找到对应的数据。
顺序表的核心特点是:数据在内存中是连续存储的。正因为数据是连续的,所以我们可以通过下标快速访问任意位置的元素。
顺序表的原理
顺序表的底层通常是用数组实现的。数组是一块连续的内存空间,每个元素都紧挨着存储。比如,我们定义一个数组 int arr[10],它就在内存中占用了 10 个连续的整数空间。
顺序表的优点:
-
访问速度快:通过下标可以直接访问元素,时间复杂度是 O(1)。
-
实现简单:用数组就能实现,代码容易理解。
顺序表的缺点:
-
插入和删除慢:如果要在中间插入或删除元素,需要移动大量数据,时间复杂度是 O(n)。
-
大小固定:数组的大小是固定的,如果数据量超过数组容量,需要重新分配更大的空间。
-
顺序表的基本操作
顺序表的基本操作包括:增、删、查、改。下面我们用大白话解释这些操作。
-
增加元素:
-
在顺序表的末尾添加一个元素很简单,直接放到最后一个空位就行。
-
如果要在中间插入元素,就需要把后面的元素都往后挪,腾出位置。
-
-
删除元素:
-
删除末尾元素很简单,直接丢掉就行。
-
如果删除中间的元素,就需要把后面的元素都往前挪,填补空缺。
-
-
查找元素:
-
通过下标可以直接找到元素,速度很快。
-
如果要根据值查找元素,需要从头到尾遍历,直到找到目标。
-
-
修改元素:
-
通过下标找到元素后,直接修改它的值就行。
-
C 语言实现顺序表
下面是一个简单的顺序表实现代码,包含初始化、插入、删除、查找和打印功能。
#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100 // 定义顺序表的最大容量// 定义顺序表结构体
typedef struct {int data[MAX_SIZE]; // 用数组存储数据int length; // 当前顺序表的长度
} SeqList;// 初始化顺序表
void InitList(SeqList *list) {list->length = 0; // 初始长度为 0
}// 插入元素
int InsertList(SeqList *list, int index, int value) {if (index < 0 || index > list->length || list->length == MAX_SIZE) {return -1; // 插入位置不合法或顺序表已满}// 将插入位置后的元素往后挪for (int i = list->length; i > index; i--) {list->data[i] = list->data[i - 1];}list->data[index] = value; // 插入新元素list->length++; // 长度加 1return 0;
}// 删除元素
int DeleteList(SeqList *list, int index) {if (index < 0 || index >= list->length) {return -1; // 删除位置不合法}// 将删除位置后的元素往前挪for (int i = index; i < list->length - 1; i++) {list->data[i] = list->data[i + 1];}list->length--; // 长度减 1return 0;
}// 查找元素
int FindList(SeqList *list, int value) {for (int i = 0; i < list->length; i++) {if (list->data[i] == value) {return i; // 返回元素的下标}}return -1; // 未找到
}// 打印顺序表
void PrintList(SeqList *list) {printf("顺序表内容:");for (int i = 0; i < list->length; i++) {printf("%d ", list->data[i]);}printf("\n");
}int main() {SeqList list;InitList(&list); // 初始化顺序表// 插入元素InsertList(&list, 0, 10); // 在第 0 个位置插入 10InsertList(&list, 1, 20); // 在第 1 个位置插入 20InsertList(&list, 2, 30); // 在第 2 个位置插入 30PrintList(&list); // 打印顺序表// 删除元素DeleteList(&list, 1); // 删除第 1 个位置的元素PrintList(&list); // 打印顺序表// 查找元素int index = FindList(&list, 30);if (index != -1) {printf("元素 30 的下标是:%d\n", index);} else {printf("未找到元素 30\n");}return 0;
}
顺序表的使用场景
-
数据量固定且需要快速访问:比如存储一周的温度数据,数据量固定,且需要快速访问某一天的温度。
-
简单的数据存储:比如存储学生的成绩列表,数据量不大,且不需要频繁插入和删除。
-
作为其他数据结构的基础:顺序表是很多高级数据结构(如栈、队列)的基础。
下面是一个顺序表的示意图:
下标: 0 1 2 3 4 数据:[10, 20, 30, 40, 50] 长度:5
-
每个格子代表一个数据元素,下标从 0 开始。
-
数据是连续存储的,就像一排小房子。
顺序表与数组的区别
顺序表和数组看起来很相似,但它们之间有一些关键的区别。为了更好地理解,我们可以把顺序表看作是一个“高级版”的数组,它在数组的基础上增加了一些功能和灵活性。
1. 数组是什么?
数组是一种最基本的数据结构,它是一块连续的内存空间,用来存储相同类型的数据。比如:
int arr[5] = {10, 20, 30, 40, 50};
数组的特点是:
-
大小固定:数组一旦定义,大小就不能改变了。
-
直接访问:通过下标可以快速访问任意位置的元素。
-
功能单一:数组只负责存储数据,没有额外的功能(比如动态扩容)。
2. 顺序表是什么?
顺序表是基于数组实现的,但它比数组更“智能”。顺序表不仅用数组存储数据,还记录了当前存储的元素个数(长度),并提供了一些常用的操作(比如插入、删除、查找等)。
顺序表的特点是:
-
动态管理:顺序表可以动态管理数据,比如插入、删除元素。
-
长度可变:顺序表的长度可以根据需要变化(虽然底层数组大小固定,但可以通过重新分配数组实现扩容)。
-
功能丰富:顺序表封装了常用的操作,使用起来更方便。
3. 顺序表和数组的区别
| 特性 | 数组 | 顺序表 |
|---|---|---|
| 大小 | 固定大小,定义后不能改变 | 可以动态扩容(需要重新分配内存) |
| 长度管理 | 需要手动记录有效元素个数 | 内部记录长度,方便管理 |
| 功能 | 只提供存储和访问功能 | 提供插入、删除、查找等操作 |
| 灵活性 | 较低,适合数据量固定的场景 | 较高,适合数据量变化的场景 |
| 实现复杂度 | 简单 | 较复杂,需要封装更多功能 |
4. 代码对比
数组的用法:
int arr[5] = {10, 20, 30, 40, 50}; // 定义一个数组
arr[2] = 100; // 修改第 3 个元素
printf("%d\n", arr[2]); // 访问第 3 个元素
顺序表的用法:
// 定义顺序表
typedef struct {int data[100]; // 底层数组int length; // 当前长度
} SeqList;// 插入元素
void InsertList(SeqList *list, int index, int value) {// 插入逻辑(需要移动元素)
}// 删除元素
void DeleteList(SeqList *list, int index) {// 删除逻辑(需要移动元素)
}// 使用顺序表
SeqList list;
list.length = 0; // 初始化长度
InsertList(&list, 0, 10); // 插入元素
DeleteList(&list, 0); // 删除元素
从代码中可以看出,顺序表比数组更“高级”,它封装了更多的功能,使用起来更方便。
5. 使用场景对比
数组的使用场景:
-
数据量固定,比如存储一周的天数(7 天)。
-
只需要简单的存储和访问,不需要频繁插入和删除。
顺序表的使用场景:
-
数据量不确定,比如存储用户输入的数据。
-
需要频繁插入、删除、查找等操作。
6. 图片对比
数组示意图:
下标: 0 1 2 3 4 数据:[10, 20, 30, 40, 50]
-
数组的大小固定为 5,无法动态扩展。
顺序表示意图:
下标: 0 1 2 3 4 5 6 7 数据:[10, 20, 30, 40, 50, _, _, _] 长度:5
-
顺序表的底层数组大小可以更大(比如 8),但只使用了前 5 个位置。
-
可以通过插入操作动态增加数据。
总结
-
数组是最基础的数据结构,适合数据量固定、操作简单的场景。
-
顺序表是基于数组实现的“高级版”,适合数据量变化、操作复杂的场景。
顺序表是一种简单而实用的数据结构,适合数据量固定且需要快速访问的场景。它的实现简单,但插入和删除操作效率较低。通过学习顺序表,我们可以更好地理解更复杂的数据结构。希望这篇文章能帮你轻松掌握顺序表!
版权声明:本文为原创文章,转载请注明出处。
相关文章:
数据结构:顺序表(Sequence List)及其实现
什么是顺序表? 顺序表是一种最简单的数据结构,它就像一排连续的小房子,每个房子里都住着一个数据元素。这些房子是按顺序排列的,每个房子都有一个门牌号(下标),我们可以通过门牌号快速找到对应…...
小程序canvas2d实现横版全屏和竖版逐字的签名组件(字帖式米字格签名组件)
文章标题 01 功能说明02 效果预览2.1 横版2.2 竖版 03 使用方式04 横向签名组件源码4.1 html 代码4.2 业务 Js4.3 样式 Css 05 竖向签名组件源码5.1 布局 Html5.2 业务 Js5.3 样式 Css 01 功能说明 技术栈:uniapp、vue、canvas 2d 需求: 实现横版的全…...
MoE演变过程
MoE演变过程 1 MoE1.1 BasicMoE1.2 SparseMoE1.2.1 实现 1.3 Shared Expert SparseMoE 1 MoE 参考:https://huggingface.co/blog/zh/moe 1.1 BasicMoE 用router给出各专家的权重,然后让输入过每一个专家,然后做加权求和。 1.2 SparseMoE …...
【Leetcode 热题 100】1287. 有序数组中出现次数超过25%的元素
问题背景 给你一个非递减的 有序 整数数组,已知这个数组中恰好有一个整数,它的出现次数超过数组元素总数的 25 % 25\% 25%。 请你找到并返回这个整数。 数据约束 1 ≤ a r r . l e n g t h ≤ 1 0 4 1 \le arr.length \le 10 ^ 4 1≤arr.length≤104 0…...
ruby 的安装
在51cto搜索的资料 ruby on rails的安装 http://developer.51cto.com/art/200906/129669.htm http://developer.51cto.com/art/200912/169391.htm http://developer.51cto.com/art/200908/147276.htm 史上最完整的ruby,rails环境架设配置(Apachefast…...
【java】List<String> fruits = new ArrayList<>(); 这一句是什么
1. 代码分解 java Copy List<String> fruits new ArrayList<>(); List<String>: List 是 Java 中的一个接口,表示一个有序的集合(可以重复元素)。 <String> 是泛型,表示这个列表中的元素…...
通俗诠释 DeepSeek-V3 模型的 “671B” ,“37B”与 “128K”,用生活比喻帮你理解模型的秘密!
欢迎来到涛涛聊AI。 在DeepSeek-V3模型的参数描述中,你可能会看到类似“671B 37B 128K”这样的标记。这些字母和数字的组合看起来像密码,但其实它们揭示了模型的“大脑容量”和“工作方式”。我们用日常生活的比喻来解释: 一、数字含义&…...
【鸿蒙Next】优秀鸿蒙博客集锦
鸿蒙基础开发:多文件压缩上传及断点续传_鸿蒙 断点续传-CSDN博客...
【实战项目】BP神经网络识别人脸朝向----MATLAB实现
(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮࿰…...
C++线程安全函数
在 C 中,线程安全的函数是指在多线程环境下可以安全调用,不会导致数据竞争或其他并发问题的函数。C 标准库提供了许多线程安全的函数,同时也要求开发者在使用自定义函数时确保线程安全。以下是一些常见的线程安全函数和实现线程安全的方法&am…...
Java中的分布式(概念说明)
1. 分布式的基本概念 1.1 什么是分布式系统? 分布式系统(Distributed System):由多台服务器(或节点)协同工作,对外提供一个整体服务。不同节点之间通过网络通信来协同处理请求或共享数据&…...
【1.8w字深入解析】从依赖地狱到依赖天堂:pnpm 如何革新前端包管理?
目录 前言npm 的诞生与发展嵌套依赖模型存在的问题npm3架构与yarnYarn 的诞生与局限Yarn 的诞生背景Yarn 仍然存在的问题 何为幽灵依赖依赖结构的不确定性pnpm王牌登场 -- 网状平铺结构安装包速度快依赖管理软链接 和 硬链接 机制 幽灵依赖产生的根本原因包管理工具的依赖解析机…...
【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑤】
ISO 14229-1:2023 UDS诊断【ECU复位0x11服务】_TestCase05 作者:车端域控测试工程师 更新日期:2025年02月17日 关键词:UDS诊断协议、ECU复位服务、0x11服务、ISO 14229-1:2023 TC11-005测试用例 用例ID测试场景验证要点参考条款预期结果TC…...
137,【4】 buuctf web [SCTF2019]Flag Shop
进入靶场 都点击看看 发现点击work会增加¥ 但肯定不能一直点下去 抓包看看 这看起来是一个 JWT(JSON Web Token)字符串。JWT 通常由三部分组成,通过点(.)分隔,分别是头部(Header&…...
Node.js 异步并发控制:`p-map` 和 `p-limit` 的使用与对比
在 Node.js 中,处理异步任务是开发中非常常见的需求。无论是批量处理数据、调用外部 API,还是操作文件系统,我们经常需要对多个异步任务进行管理。然而,当任务数量较多时,如果不加以控制,并发可能会导致性能…...
【c++】c++内存管理
目录 c和c的内存分布回顾C语言动态管理内存的方式malloccallocreallocfree C动态管理内存的方式new和deleteoperator new和operator delete定位new c和c的内存分布 回顾C语言动态管理内存的方式 malloc void* malloc (size_t size);malloc可以在堆上开辟指定内存的空间&#…...
EtherNet/IP转Modbus TCP:新能源风电监控与分析实用案例
EtherNet/IP转Modbus TCP:新能源风电监控与分析实用案例 一、案例背景 在某新能源汽车电池生产线上,需要将采用EtherNet/IP协议的电池检测设备与采用ProfiNet协议的生产线控制系统进行集成,以实现对电池生产过程的全面监控和数据采集。 二、…...
伪装目标检测(Camouflaged Object Detection, COD)教程
1. 引言 伪装目标检测(Camouflaged Object Detection, COD)是一项计算机视觉任务,旨在识别和分割背景中难以察觉的目标,如动物伪装、隐形物体检测等。由于伪装目标通常与背景高度相似,这项任务比传统的目标检测更具挑…...
烧烤炉出口亚马逊欧盟站CE认证EN1860安全标准
什么是欧盟CE认证: 在欧盟市场“CE”标志属强制性认证标志,不论是欧盟内部企业生产的产品,还是其他国家生产的产品,要想在欧盟市场上自由流通,就必须加贴“CE”标志,以表明产品符合欧盟《技术协调与标准化新…...
动态DNS神器nip.io使用指南:快速实现域名与IP的动态映射--告别配置本地hosts
动态DNS神器nip.io使用指南:快速实现域名与IP的动态映射--告别配置本地hosts 一、项目简介二、快速入门三、进阶配置四、典型应用场景 本文基于开源项目 v1.2.1版本撰写,适用于开发测试、CI/CD等场景 一、项目简介 nip.io 是由Exentrique Solutions开发…...
人工智能 - 机器学习、深度学习、强化学习是人工智能领域的理论基础和方法论
机器学习、深度学习、强化学习是人工智能领域的三大核心方向,各自具有独特的理论基础和方法论。以下是它们的核心理论知识总结: 一、机器学习(Machine Learning, ML) 1. 基础概念 目标:通过数据驱动的方式,让机器从经验中学习规律,完成预测、分类或决策任务。 核心范式…...
数字电路-基础逻辑门实验
基础逻辑门是数字电路设计的核心元件,它们执行的是基本的逻辑运算。通过这些基本运算,可以构建出更为复杂的逻辑功能。常见的基础逻辑门包括与门(AND)、或门(OR)、非门(NOT)、异或门…...
国产编辑器EverEdit - 如虎添翼的功能:快速选择
1 快速选择 1.1 应用场景 快速选择适用于批量选择和修改的场景,比如:变量改名。 1.2 使用方法 1.2.1 逐项快速选择 将光标放置在单词前或单词中,选择主菜单查找 -> 快速选择 -> 快速选择或使用快捷键Ctrl D 注:光标放…...
国内外网络安全政策动态(2025年1月)
▶︎ 1.国家互联网信息办公室发布《个人信息出境个人信息保护认证办法(征求意见稿)》 1月3日,国家互联网信息办公室发布《个人信息出境个人信息保护认证办法(征求意见稿)》。根据《意见稿》,个人信息出境个…...
68页PDF | 数据安全总体解决方案:从数据管理方法论到落地实践的全方位指南(附下载)
一、前言 这份报告旨在应对数字化转型过程中数据安全面临的挑战,并提供全面的管理与技术体系建设框架。报告首先分析了数字化社会的发展背景,强调了数据安全在国家安全层面的重要性,并指出数据安全风险的来源和防护措施。接着,报…...
AI大模型的文本流如何持续吐到前端,实时通信的技术 SSE(Server-Sent Events) 认知
写在前面 没接触过 SSE(Server-Sent Events),AI大模型出来之后,一直以为文本流是用 WebSocket 做的偶然看到返回到报文格式是 text/event-stream,所以简单认知,整理笔记博文内容涉及 SSE 认知,以及对应的 D…...
Electron:使用electron-react-boilerplate创建一个react + electron的项目
使用 electron-react-boilerplate git clone --depth 1 --branch main https://github.com/electron-react-boilerplate/electron-react-boilerplate.git your-project-name cd your-project-name npm install npm start 安装不成功 在根目录加上 .npmrc文件 内容为 electron_…...
Spring Boot三:Springboot自动装配原理
精心整理了最新的面试资料,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 原理初探 pom.xml 核心依赖在父工程中 spring-boot-dependencies所有的jar包都在这里管理 我们在写或者引入一些依赖的时候,不需要指定版本 启动器 <…...
【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十八节】
ISO 14229-1:2023 UDS诊断服务测试用例全解析(ResponseOnEvent_0x86服务) 作者:车端域控测试工程师 更新日期:2025年02月14日 关键词:UDS协议、0x86服务、事件响应、ISO 14229-1:2023、ECU测试 一、服务功能概述 0x86…...
Qt 中使用 SQLite 数据库的完整指南
SQLite 是一款轻量级、嵌入式的关系型数据库,无需独立的服务器进程,数据以文件形式存储,非常适合桌面和移动端应用的本地数据管理。Qt 通过 Qt SQL 模块提供了对 SQLite 的原生支持,开发者可以轻松实现数据库的增删改查、事务处理…...
