news 2026/5/21 3:54:03

数据结构顺序表

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据结构顺序表

1、线性表

线性表(linearlist):是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

2、顺序表

2.1、概念与结构

概念:顺序表是⽤⼀段物理地址连续的存储单元依次存储数据元素的线性结构,⼀般情况下采用数组存储。

结构:

顺序表和数组的区别
顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口
类比于:

2.2、分类

2.2.1静态顺序表

概念:使用定长数组存储元素

静态顺序表缺陷:空间给少了不够用,给多了造成空间浪费

2.2.2动态顺序表

概念:可以按需申请空间,减少空间浪费

2.3、动态顺序表的实现

动态顺序表实现所用到的4种方法(尾插、头插、尾删、头删)

2.3.1尾插法

结构理解图:

在VIsual Studio 2022中进行代码编写

先定义一个头文件SeqList.h 在头文件内进行初始化、以及尾插的定义

//尾插 void SLPushBack(SL* ps, SLDatatype x);

再创建一个源文件SeqList.c 在源文件内进行尾插的编写

//尾插 void SLPushBack(SL* ps, SLDatatype x) { assert(ps); //判断空间是否足够 SLCheckCapacity(ps); //空间足够的情况下 ps->arr[ps->size++] = x; }

最后创建一个测试文件test.c 让编写的代码在test.c中实现编译

void test01() { SL s1; SLInit(&s1); SLPushBack(&s1, 1); SLPushBack(&s1, 2); SLPushBack(&s1, 3); SLPushBack(&s1, 4); SLPrint(&s1); }

2.3.2头插法

结构理解图:

在头文件中加入对头插法的定义

//头插 void SLPushFront(SL* ps, SLDatatype x);

在源文件SeqList.c内进行头插的编写

//头插 void SLPushFront(SL* ps, SLDatatype x) { assert(ps); //判断空间是否足够 SLCheckCapacity(ps); //将顺序表中所有数据向后挪动一位 for (int i = ps->size; i > 0; i--) { ps->arr[i] = ps->arr[i - 1]; } ps->arr[0] = x; ps->size++; }

最后创建一个测试文件test.c 让编写的代码在test.c中实现编译

void test01() { SL s1; SLInit(&s1); SLPushFront(&s1, 1); SLPushFront(&s1, 2); SLPushFront(&s1, 3); SLPushFront(&s1, 4); SLPrint(&s1); }

2.3.3尾删法

结构理解图:(将3删除,顺序表中数据为0,1,2)

在头文件中加入对尾删法的定义

//尾删 void SLPopBack(SL* ps);

在源文件SeqList.c内进行尾删的编写

//尾删 void SLPopBack(SL* ps) { //在此处断言:ps不能为NULL ps->size为NULL(顺序表为空不能实现尾删) assert(ps && ps->size); ps->size--; }

最后创建一个测试文件test.c 让编写的代码在test.c中实现编译

void test01() { SL s1; SLInit(&s1); SLPushBack(&s1, 1); SLPushBack(&s1, 2); SLPushBack(&s1, 3); SLPushBack(&s1, 4); SLPrint(&s1); SLPopBack(&s1); SLPrint(&s1); SLPopBack(&s1); SLPrint(&s1); SLPopBack(&s1); SLPrint(&s1); SLPopBack(&s1); SLPrint(&s1); }

2.3.4头删法

结构理解图:

在头文件中加入对头删法的定义

//头删 void SLPopFront(SL* ps);

在源文件SeqList.c内进行头删的编写

//头删 void SLPopFront(SL* ps) { assert(ps && ps->size); for (int i = 0; i < ps->size - 1; i++) { ps->arr[i] = ps->arr[i + 1]; } ps->size--; }

最后创建一个测试文件test.c 让编写的代码在test.c中实现编译

void test01() { SL s1; SLInit(&s1); SLPushBack(&s1, 1); SLPushBack(&s1, 2); SLPushBack(&s1, 3); SLPushBack(&s1, 4); SLPrint(&s1); SLPopFront(&s1); SLPrint(&s1); SLPopFront(&s1); SLPrint(&s1); SLPopFront(&s1); SLPrint(&s1); }

2.3.5在指定位置之前插入数据

结构理解图:

在头文件中加入对指定位置插入的定义

//在指定位置之前插入数据 void SLInsert(SL* ps, int pos, SLDatatype x);

在源文件SeqList.c内进行对指定位置插入的编写

//在指定位置之前插入 void SLInsert(SL* ps, int pos, SLDatatype x) { assert(ps); assert(pos >= 0 && pos <= ps->size); SLCheckCapacity(ps); for (int i = ps->size; i > pos; i--) { ps->arr[i] = ps->arr[i - 1]; } ps->arr[pos] = x; ps->size++; }

最后创建一个测试文件test.c 让编写的代码在test.c中实现编译

void test01() { SL s1; SLInit(&s1); SLPushBack(&s1, 1); SLPushBack(&s1, 2); SLPushBack(&s1, 3); SLPushBack(&s1, 4); SLPrint(&s1); SLInsert(&s1, 4, 100); SLPrint(&s1); }

2.3.6删除指定位置数据

在头文件中加入对删除指定位置的定义

//删除插入位置数据 void SLErase(SL* ps, int pos);

在源文件SeqList.c内进行删除指定位置数据的编写

//删除指定位置数据 void SLErase(SL* ps, int pos) { assert(ps); assert(pos >= 0 && pos <= ps->size); //pos之后的数据整体向前挪动一位 for (int i = pos; i < ps->size - 1; i++) { ps->arr[i] = ps->arr[i + 1]; } --ps->size; }

最后创建一个测试文件test.c 让编写的代码在test.c中实现编译

void test01() { SL s1; SLInit(&s1); SLPushBack(&s1, 1); SLPushBack(&s1, 2); SLPushBack(&s1, 3); SLPushBack(&s1, 4); SLPrint(&s1); SLErase(&s1, 3); SLPrint(&s1); }

2.3.7查找数据

在头文件中加入对查找数据的定义

//查找数据 int SLFind(SL* ps, SLDatatype x);

在源文件SeqList.c内进行查找数据的编写

//查找数据 int SLFind(SL* ps, SLDatatype x) { for(int i = 0; i < ps->size; i++ ) { if (ps->arr[i] = x) { return i; } } return -1; }

最后创建一个测试文件test.c 让编写的代码在test.c中实现编译

void test01() { SL s1; SLInit(&s1); SLPushBack(&s1, 1); SLPushBack(&s1, 2); SLPushBack(&s1, 3); SLPushBack(&s1, 4); SLPrint(&s1); int find = SLFind(&s1, 2); if (find != -1) { printf("找到了 \n"); } else { printf("未找到 \n"); } SLDestroy(&s1); }

2.3.8销毁顺序表

在头文件中加入对销毁数据表的定义

//销毁顺序表 void SLDestroy(SL* ps);

在源文件SeqList.c内进行销毁数据表的编写

//销毁顺序表 void SLDestroy(SL* ps) { assert(ps); if (ps->arr) free(ps->arr); ps->arr = NULL; ps->size = ps->capacity = 0; }

最后创建一个测试文件test.c 让编写的代码在test.c中实现编译

void test01() { SL s1; SLInit(&s1); SLPushBack(&s1, 1); SLPushBack(&s1, 2); SLPushBack(&s1, 3); SLPushBack(&s1, 4); SLPrint(&s1); SLDestroy(&s1); }

最后通过调试可以发现顺序表被销毁

总结:上述完整代码链接

顺序表完整代码仓

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 3:47:41

Codex使用DeepSeek API的方法(cc switch + codex bridge方案)

一、背景 OpenAI 的 Codex 是目前主流的 AI 编程助手之一&#xff0c;不仅可以用来编写代码&#xff0c;还可以用于办公&#xff0c;生活服务等。操作浏览器&#xff0c;操作电脑更是将要抢占龙虾的地位。 DeepSeek V4 在代码场景下性价比高、API 成本低。 两者无法直接对接&…

作者头像 李华
网站建设 2026/5/21 3:42:01

晶振参数深度解读与替代选型实战(55.2MHz 工业级无源晶振案例)

前言作为嵌入式 / 硬件 FAE&#xff0c;日常工作中晶振的参数解读、客户需求替代是高频场景。最近遇到一个典型的工业级宽温晶振客户需求&#xff0c;参数里藏着很多新手容易踩的坑&#xff0c;比如 “负频率” 的误解、负载电容不匹配、宽温范围忽略等问题。本文以客户的55.2M…

作者头像 李华
网站建设 2026/5/21 3:33:04

射灯轨道灯怎么选?看完这篇不花冤枉钱! 这几家射灯轨道灯公司靠谱吗?老师傅偷偷告诉你! 装修小白必看:射灯轨道灯避坑指南,这家公司口碑最好!

朋友们&#xff0c;最近是不是被家里或者店铺的灯光搞得头大&#xff1f;想装射灯轨道灯提升一下格调&#xff0c;结果一搜&#xff0c;从几十块到几百块一盏的都有&#xff0c;品牌五花八门&#xff0c;参数看得人眼花缭乱。买便宜的怕效果差&#xff0c;买贵的又怕被坑。今天…

作者头像 李华
网站建设 2026/5/21 3:32:41

SpringBoot 实现动态切换数据源,这样做才足够优雅!

点击上方“java大数据修炼之道”, 选择“设为星标”技术干货发文后 &#x1f449; 第一时间奉上最近在做业务需求时&#xff0c;需要从不同的数据库中获取数据然后写入到当前数据库中&#xff0c;因此涉及到切换数据源问题。本来想着使用Mybatis-plus中提供的动态数据源SpringB…

作者头像 李华
网站建设 2026/5/21 3:29:02

KING大咖直播|驯服时间洪流:电科金仓KES时序版“硬核”解码

设备互联、生产监控、交易行情……时序数据正以指数级速度狂奔&#xff0c;传统数据库频频掉队&#xff1f;电科金仓KES时序版&#xff0c;用“一库多模”破题&#xff1a;千万级并发写入稳如磐石、20倍压缩比瘦身立现、高密度写入与实时分析同框——这是国产时序数据库交出的一…

作者头像 李华