数据结构—顺序表
目录
1.线性表
2.顺序表概念
3.实现顺序表
(1)声明结构体
(2)初始化
(3)打印数据
(4) 销毁
(5)尾插&头插
尾插
判断是否扩容
头插
(6)尾删&头删
尾删
头删
(7)指定位置插入元素
(8)删除指定位置元素
(9)查找指定元素位置
(10)修改指定位置元素
完整版附上:
Seqlist.h
text.c
Seqlist.c
1.线性表
- 线性表是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
- 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,
- 线性表在物理上存储时,通常以数组和链式结构的形式存储。
2.顺序表概念
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
2. 动态顺序表:使用动态开辟的数组存储。

3.实现顺序表
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用 动态顺序表 ,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。
我们创建三个文件:
- Seqlist.h用于存放头文件、结构体和函数的声明
- text.c作为主程序进行运行和测试
- Seqlist.c存放函数主体
(1)声明结构体
#include <stdio.h>typedef int SLDatatype;
typedef struct SeqList
{SLDatatype* a;int size;int capacity;
}SL;
- 在头文件中声明结构体struct SeqList,由于名字太长,我们用typedef自定义结构体名称的别名为SL。
- 将顺序表的数据类型用SLDatatype这个别名代替int,以后程序中使用到元素数据类型时都替换成SLDatatype,方便日后修改顺序表数据类型。
- 定义size存储当前元素个数,capacity存储顺序表容量。
(2)初始化
void SLInit(SL* psl)
{assert(psl);psl->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);if (psl->a == NULL) {perror("malloc fail");return;}psl->size = 0;psl->capacity = 4;
}
- 需要改变结构体变量,则将其地址传入函数。
- assert检测传参顺序表指针是否合法,如果传入参数为空则报错(具体哪行出错)。
- 然后为结构体成员a分配4个成员类型空间,顺便检查是否分配成功。
- 对成员size和capacity分别复制为0(当前元素个数)和4(顺序表容量)。
(3)打印数据
void SLPrint(SL* psl)
{assert(psl);for (int i = 0; i < psl->size; i++) {printf("%d ", psl->a[i]);}
}
- assert检测传参顺序表指针是否合法,然后循环遍历输出。
(4) 销毁
void SLDestroy(SL* psl)
{assert(psl);free(psl->a);psl->a = NULL;psl->size = 0;psl->capacity = 0;
}
- assert检测传参顺序表指针是否合法。
- 释放动态开辟a的空间,同时赋值为空,不置空可能会造成野指针的访问。
- size和capacity分别赋值为0。
(5)尾插&头插
尾插
void SLPushBack(SL* psl, SLDatatype x)
{assert(psl);SLCheckCapacity(psl);psl->a[psl->size] = x;psl->size++;
}
- assert检测传参顺序表指针是否合法。
- 判断数组是否已经装满,如果装满则进行扩容,这些操作我们在函数SLCheckCapacity内进行。
- 将
x赋值给psl->a数组中下一个可用的位置,即psl->size索引处。 - 递增
psl->size,以便记录新元素的加入。
接下来我们来讲解函数SLCheckCapacity:
判断是否扩容
void SLCheckCapacity(SL* psl)
{if (psl->size == psl->capacity) {SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * psl->capacity * 2);if (tmp == NULL) {perror("realloc fail");return;}psl->a = tmp;psl->capacity *= 2;}
}
- 判断当前元素个数size与顺序表容量capacity是否相等,相等则对结构体成员指针a进行扩容。
- 通过realloc函数对a的内存进行扩容,每次增加一倍容量,并将reallocd的返回值新空间的起始地址赋值给SLDatatype类型指针 tmp,这样避免直接对a开辟空间时发生错误丢失数据。
- 检测是否成功扩容。
- 最后将存放新空间地址的tmp赋值给a。
- 顺序表的容量也随之扩大为原来的两倍。
我们还可以优化一下尾插函数,具体如下:
void SLPushBack(SL* psl, SLDatatype x)//尾插
{SLCheckCapacity(psl);psl->a[psl->size++] = x;
}
头插
void SLPushFront(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++;
}
- assert检测传参顺序表指针是否合法。
- 判断数组是否已经装满,如果装满则进行扩容,这些操作在函数SLCheckCapacity内进行。
- 定义end表示当前顺序表中最后一个元素的下标。
- while循环用于从后向前将顺序表中的元素依次向后移动一个位置,为新元素
x腾出空间 - 将新元素
x插入到顺序表的开头 - 顺序表元素个数
size增加1
(6)尾删&头删
尾删
void SLPopBack(SL* psl)
{assert(psl);//暴力判断assert(psl->size == 0);//常规判断//if (psl->size == 0)// return;psl->a[psl->size - 1] = 0;psl->size--;
}
- 第一个assert检测传参顺序表指针是否合法。
- 第二个assert检测顺序表是否为空,为空没有元素则不需要删除,程序报错。
- 我们还可以通过顺序表元素个数判断,if语句判断size为0时,函数停止运行。
- 顺序表大小不为空,则对最后一个元素进行删除,赋值为0。
- 顺序表大小size减1.
头删
void SLPopFront(SL* psl)
{assert(psl);assert(psl->size > 0);int start = 0;while (start < psl->size) {psl->a[start] = psl->a[start + 1];start++;}psl->size--;
}
- 第一个assert检测传参顺序表指针是否合法。
- 第二个assert检测顺序表是否为空,为空没有元素则不需要删除,程序报错。
- 定义变量start为首元素下标.
- 头删不用赋值为0,直接从第一个元素开始后项赋值给前项。
(7)指定位置插入元素
void SLInsert(SL* psl, int pos, SLDatatype x)
{assert(psl);assert(0 <= pos && pos <= psl->size);SLCheckCapacity(psl);int end = psl->size - 1;while (end > 0) {psl->a[end + 1] = psl->a[end];end--;}psl->size++;psl->a[pos] = x;
}
- 参数pos为要在第几个元素后插入。
- 第一个assert检测传参顺序表指针是否合法。
- 第二个assert检测传参pos的位置是否合法。
- 判断数组是否已经装满,如果装满则进行扩容,这些操作在函数SLCheckCapacity内进行。
- 定义end表示当前顺序表中最后一个元素的下标。
- while循环用于从后向前将顺序表中的元素依次向后移动一个位置,为新元素
x腾出空间 - 顺序表元素个数
size增加1。 - 将新元素
x插入到顺序表指定元素位置之后。
SLInsert这个函数可以代替头插尾插函数进行顺序表元素的增加。
(8)删除指定位置元素
void SLErase(SL* psl, int pos)
{assert(psl);assert(0 <= pos && pos <= psl->size);int start = pos + 1;while (start < psl->size) {psl->a[start - 1] = psl->a[start];start++;}psl->size--;
}
- 第一个assert检测传参顺序表指针是否合法。
- 第二个assert检测传参pos的位置是否合法。
- 定义变量start存储pos位置后一项的下标。
- 将删除元素后一项位置的值开始从pos+1向后依次前移一位,顶替pos位置。
- 顺序表元素个数减一。
这个函数就可以完全代替头删尾删了。
(9)查找指定元素位置
int SLFind(SL* psl, SLDatatype x)
{assert(psl);for (int i = 0; i < psl->size; i++) {if (psl->a[i] == x)return i+1;}return -1;
}
- assert检测传参顺序表指针是否合法。
- 循环遍历顺序表找出于x相等的元素,返回其下标。
- 找不到返回-1。
(10)修改指定位置元素
void SLModify(SL* psl, int pos, SLDatatype x)
{assert(psl);assert(0 <= pos && pos <= psl->size);psl->a[pos] = x;
}
- 第一个assert检测传参顺序表指针是否合法。
- 第二个assert检测传参pos的位置是否合法。
-
将pos位置的值修改为x。
完整版附上:
Seqlist.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDatatype;
typedef struct SeqList
{SLDatatype* a;int size;int capacity;
}SL;void SLInit(SL* psl);
void SLDestroy(SL* psl);
void SLPrint(SL* psl);
void SLPushBack(SL* psl, SLDatatype x);
void SLPushFront(SL* psl, SLDatatype x);
void SLPopBack(SL* psl);
void SLPopFront(SL* psl);
void SLInsert(SL* psl, int pos, SLDatatype x);
void SLErase(SL* psl, int pos);
int SLFind(SL* psl, SLDatatype x);
void SLModify(SL* psl, int pos, SLDatatype x);
text.c
这里大家可以自行发挥!
#define _CRT_SECURE_NO_WARNINGS 1
#include "Seqlist.h"void test1()
{SL s;SLInit(&s);SLPushBack(&s, 5);SLPushBack(&s, 9);SLPushBack(&s, 50);SLPushFront(&s, 1);SLPushFront(&s, 15);SLPushFront(&s, 0);SLPopBack(&s, 50);SLPopFront(&s, 0);SLInsert(&s, 2, 555);SLErase(&s, 4);SLPrint(&s);int a=SLFind(&s, 15);printf("\n%d\n", a);if (a != -1)SLErase(&s, a);SLPrint(&s);SLDestroy(&s);
}int main()
{test1();return 0;
}
Seqlist.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Seqlist.h"void SLInit(SL* psl)//初始化
{assert(psl);psl->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);if (psl->a == NULL) {perror("malloc fail");return;}psl->size = 0;psl->capacity = 4;//每次开辟的容量为四个
}void SLPrint(SL* psl)//打印数据
{assert(psl);for (int i = 0; i < psl->size; i++) {printf("%d ", psl->a[i]);}
}void SLDestroy(SL* psl)//结束使用需要销毁
{assert(psl);free(psl->a);psl->a = NULL;psl->size = 0;psl->capacity = 0;
}void SLCheckCapacity(SL* psl)
{if (psl->size == psl->capacity) {//增加一倍容量SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * psl->capacity * 2);if (tmp == NULL) {perror("realloc fail");return;}psl->a = tmp;psl->capacity *= 2;}}void SLPushBack(SL* psl, SLDatatype x)//尾插
{assert(psl);//psl->a[psl->size] = x;//psl->size++;//插入需要判断a是否已满,已满需要扩容SLCheckCapacity(psl);//或者写成一句psl->a[psl->size++] = x;//后置自增
}void SLPushFront(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++;
}
void SLPopBack(SL* psl)
{assert(psl);//尾删//暴力判断//assert(psl->size == 0);//常规判断if (psl->size == 0)return;psl->a[psl->size - 1] = 0;psl->size--;
}void SLPopFront(SL* psl)//头删
{assert(psl);assert(psl->size > 0);int start = 0;while (start < psl->size) {psl->a[start] = psl->a[start + 1];start++;}psl->size--;
}void SLInsert(SL* psl, int pos, SLDatatype x)//指定位置插入元素,可代替头插尾插
{assert(psl);assert(0 <= pos && pos <= psl->size);//判读插入位置是否合法SLCheckCapacity(psl);int end = psl->size - 1;while (end > 0) {psl->a[end + 1] = psl->a[end];end--;}psl->size++;psl->a[pos] = x;
}void SLErase(SL* psl, int pos)//删除指定位置元素,代替头删尾删
{assert(psl);assert(0 <= pos && pos <= psl->size);int start = pos + 1;while (start < psl->size) {psl->a[start - 1] = psl->a[start];start++;}psl->size--;
}int SLFind(SL* psl, SLDatatype x)//查找指定元素位置
{assert(psl);for (int i = 0; i < psl->size; i++) {if (psl->a[i] == x)return i+1;}return -1;//找不到返回-1
}void SLModify(SL* psl, int pos, SLDatatype x)//修改指定位置元素
{assert(psl);assert(0 <= pos && pos <= psl->size);psl->a[pos] = x;
}
相关文章:
数据结构—顺序表
目录 1.线性表 2.顺序表概念 3.实现顺序表 (1)声明结构体 (2)初始化 (3)打印数据 (4) 销毁 (5)尾插&头插 尾插 判断是否扩容 头插 (6)尾删&头删 尾删 头删 (7)指定位置插入元素 (8)删除指定位置元素 (9)查找指定元素位置 (10)修改指定位置元素 完整版…...
企业服务器租用对性能有什么要求呢?
企业租用服务器租用首要的是稳定,其次是安全,稳定是为了让企业的工作能够顺利进行,只有性能稳定的服务器才能保证网站之类的正常工作,就让小编带大家看一看有什么要求吧! 服务器简单介绍。服务器是在网络上为其它客户机…...
2731.移动机器人
2731. 移动机器人 - 力扣(LeetCode) 有一些机器人分布在一条无限长的数轴上,他们初始坐标用一个下标从 0 开始的整数数组 nums 表示。当你给机器人下达命令时,它们以每秒钟一单位的速度开始移动。 给你一个字符串 s ,…...
相交链表Java
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 nu11。 以下有两种解决方法: 一种是用Map,利用其key值唯一的方法去判断(也可以使用set,set在add时,已存在的元素会返回false,不存在的返回…...
第二章:OSI参考模型与TCP/IP模型
OSI参考模型与TCP/IP模型 一、OSI参考模型二、TCP/IP模型2.1 四层分法(书上)2.2 五层分法(实际厂商)2.3 数据封装和解封装2.3.1 封装2.3.2 解封装2.3.3 TCP/IP分层封装2.3.4 数据封装和解封装过程 一、OSI参考模型 1.物理层 定义电…...
知识图谱04——openGL与ubuntu22.04
跑图神经网络的时候遇到了如下问题 libGL error: failed to load driver: iris libGL error: MESA-LOADER: failed to open iris: /usr/lib/dri/iris_dri.so: 无法打开共享对象文件: 没有那个文件或目录 (search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/li…...
如何看待为了省小钱而花费时间
相信每个人都会遇到这种情况:购买东西时想着货比三家或者想办法领优惠券、凑单等就可以省下一些钱,但是需要花费不少时间和精力。这时就开始犹豫了:省钱是必要的,需要居安思危,等到缺钱的时候不会后悔;又想…...
Maven Eclipse
Eclipse 提供了一个很好的插件 m2eclipse ,该插件能将 Maven 和 Eclipse 集成在一起。 在最新的 Eclipse 中自带了 Maven,我们打开,Windows->Preferences,如果会出现下面的画面: 下面列出 m2eclipse 的一些特点&a…...
Linux:redis集群(3.*版本 和 5.*版本)搭建方法
介绍 至少6个实例才能组成集群。3主3从会自动分配 Redis集群原理 Redis集群架构 Redis Cluster采用虚拟槽分区,将所有的数据根据算法映射到0~16383整数槽内 Redis Cluster是一个无中心的结构 每个节点都保存数据和整个集群的状态 集群角色 Master:Master…...
正则表达式基础语法
https://tool.oschina.net/regex 正则表达式:检查、匹配字符串的表达式 单个字符匹配: 有特殊含义的匹配: 多次重复匹配: 限定开头结尾的匹配: 贪婪模式:在满足条件的情况下,尽可能多匹配…...
数据库常见面试题--MySQL
梳理面试过程中数据库相关的常见问题,需要说明的是,这篇文章主要是基于MySQL数据库,其他类型的数据库还请自行参考使用。 数据库概述 为什么使用数据库 1、数据库增删改查更方便 2、提供了事务的能力 本质是更好的管理数据。 数据库体系结…...
Springboot 集成 Redis集群配置公网IP连接报私网IP连接失败问题
1、问题:在Springboot 集成 Redis集群配置公网IP连接报私网IP连接失败,一直报私有IP连接失败 14 14:57:49.180 WARN 22012 --- [ioEventLoop-6-4] i.l.c.c.topology.ClusterTopologyRefresh : Unable to connect to [192.168.0.19:6384]: connection …...
解决方案 | 法大大电子签精准击破销售场景签约难题
新商业形态及新交易模式不断涌现,电子签已经成为现代商业活动中不可或缺的一部分。特别是在销售场景中,电子签的应用不仅可以提高销售效率,还可以降低成本,提高客户满意度。本文将详细分析电子签在销售场景中的应用价值能力&#…...
ARM按键中断控制事件
设置按键中断,按键1按下,LED亮,再按一次,灭按键2按下,蜂鸣器响。再按一次,不响按键3按下,风扇转,再按一次,风扇停 src/key_it.c #include"key_it.h" //GPIO初…...
微信小程序之本地生活(九宫格)
文章目录 一.创建项目二.配置修改json三.编写WXML四.编写WXSS五.最终效果 一.创建项目 创建新的项目,名称为:本地生活 二.配置修改json 在app.json中删除其他页面 将index改为grid 自动生成新的文件 添加自己的轮播图片 源代码: <!--…...
【Linux 安装Kibana 及 Es 分词器安装】
一、客户端Kibana安装 Kibana是一个开源分析和可视化平台,旨在与Elasticsearch协同工作。参考文档 1. 下载并解压缩Kibana 下载路径 选择的版本是和 ElasticSearch 对应(7.17.3) 下载后上传到Linux 系统中,并放在 /root/ 下&a…...
python-arima模型statsmodels库实现-有数据集(续)-statsmodels-0.9.0版本
python-arima模型statsmodels库实现-有数据集(续) 这篇博客是上一篇python-arima模型statsmodels库实现的续集,上一篇采用的statsmodels版本应该要高一点,如果使用低版本的statsmodels代码会有bug,这一篇则是针对stat…...
JVM源码剖析之线程的创建过程
说在前面: 对于Java线程的创建这个话题,似乎已经被"八股文"带偏~ 大部分Java程序员从"八股文"得知创建Java线程有N种方式,比如new Thread、new Runnable、Callable、线程池等等~ 而笔者写下这篇文…...
ansible的介绍安装与模块
目录 一、ansible简介 二、ansible特点 三、Ansible核心组件与工作原理 1、核心组件 2、工作原理 四、ansible的安装 五、ansible 命令行模块 1.command 模块 2.shell 模块 3.cron 模块 4.user 模块 5.group 模…...
el-form简单封装一个列表页中的搜索栏
父组件如何使用 代码中注释很多, 应该很容易理解 <template><div><wgySearchv-model"searchDefault":fields"searchFields"reset"reset"submit"submit"><!-- 通过 slot 自定义的组件 传啥都行 --><te…...
FastAPI CSP:实现配置的终极指南
FastAPI CSP:实现配置的终极指南 【免费下载链接】fastapi FastAPI framework, high performance, easy to learn, fast to code, ready for production 项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi FastAPI是一个高性能、易于学习、快速编码…...
iOS开发效率工具:设备支持文件管理完全指南 - 无需升级Xcode的解决方案
iOS开发效率工具:设备支持文件管理完全指南 - 无需升级Xcode的解决方案 【免费下载链接】iOSDeviceSupport All versions of iOS Device Support 项目地址: https://gitcode.com/gh_mirrors/ios/iOSDeviceSupport 作为iOS开发者,你是否曾遭遇这样…...
ai赋能centos7开发,用快马平台智能生成优化配置和部署流水线
最近在折腾CentOS7的开发环境配置,发现手动搭建Python/Java环境、调试服务编排特别耗时。后来尝试用InsCode(快马)平台的AI辅助功能,效率直接翻倍。分享下我的实践过程: 环境配置方案生成 输入"CentOS7 Python3.9Java11开发环境"后…...
Phi-4-mini-reasoning开源大模型教程:免配置镜像+128K长文本推理实战
Phi-4-mini-reasoning开源大模型教程:免配置镜像128K长文本推理实战 1. 模型简介 Phi-4-mini-reasoning是一个轻量级开源大语言模型,专注于高质量推理任务。作为Phi-4模型家族成员,它具备以下核心特点: 推理能力突出࿱…...
如何快速配置TranslucentTB:Windows任务栏美化终极教程
如何快速配置TranslucentTB:Windows任务栏美化终极教程 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 想要让Windows任务栏变…...
Linux服务器日志爆满?5个实用命令快速定位并清理大日志文件
Linux服务器日志爆满?5个实用命令快速定位并清理大日志文件 当服务器磁盘空间告急时,日志文件往往是罪魁祸首。作为系统管理员,我们需要快速定位问题并安全清理,避免服务中断。本文将分享5个核心命令的组合使用技巧,帮…...
离谱了,简历写了这个项目薪资直接涨了 80%!!
报喜了!!!前阵子帮一个粉丝修改简历,只是在项目经历里加了一个“不起眼”的项目,优化了表述逻辑,没想到他面试3家公司,2家给了offer,薪资直接比上一份涨了80%!其实很多人…...
30天小白进阶AI大神:收藏这份路线图,免费工具玩转大模型!
本文为AI学习新手提供了30天的系统学习路线图,涵盖了AI技术栈的三个层次:应用层、模型层和基础设施层。文章建议从应用层入手,逐步向下理解,并推荐了主流AI工具的对比及免费工具的入门使用。此外,还提供了给初学者的五…...
Qwen3-ASR-0.6B作品集:Qwen3-ForcedAligner-0.6B时间戳精度图谱
Qwen3-ASR-0.6B作品集:Qwen3-ForcedAligner-0.6B时间戳精度图谱 你有没有想过,一段语音里的每个字、每个词,甚至每个音节,是在哪个精确的时间点被说出来的?这听起来像是电影后期制作里的黑科技,但现在&…...
ClawdBot代码实例:修改clawdbot.json实现模型热切换实操
ClawdBot代码实例:修改clawdbot.json实现模型热切换实操 1. 引言:你的个人AI助手,想换模型就换模型 想象一下,你有一个24小时在线的AI助手,它能帮你写代码、回答问题、整理文档。但用久了,你可能会想&…...
