数据结构:顺序表(C实现)

个人主页 水月梦镜花
个人专栏 C语言 ,数据结构
文章目录
- 一、顺序表
- 二、实现思路
- 1.存储结构
- 2.初始化顺序表(SeqListInit)
- 3.销毁顺序表(SeqListDestroty)
- 4.打印顺序表(SeqListPrint)
- 5.顺序表尾插(SeqListPushBack)and检查容量(SeqListCheckCapacity)
- 6.顺序表头插(SeqLsitPushFront)
- 7.顺序表尾删(SeqListPopBack)
- 8.顺序表头删(SeqListPopFront)
- 9.顺序表查找(SeqListFind)
- 10.在pos位置前插入元素(SeqListInsert)
- 11.删除pos位置的值(SeqListErase)
- 三、代码实现
- 总结
一、顺序表
顺序表是用一段物理结构连续的存储单元依次存储数据元素的线性结构,一般采用数组存储。
顺序表一般分为两种:
- 静态顺序表:使用定长数组实现
- 动态顺数表:使用动态开辟的数组实现
本篇文章,顺序表是使用动态开辟的数组实现(动态顺序表)。要实现的功能如下:
//初始化顺序表
void SeqListInit(SeqList* ps);//销毁顺序表
void SeqListDestroty(SeqList* ps);//打印顺序表
void SeqListPrint(SeqList* ps);//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDateType x);//顺序表头插
void SeqLsitPushFront(SeqList* ps, SLDateType x);//顺序表尾删
void SeqListPopBack(SeqList* ps);//顺序表头删
void SeqListPopFront(SeqList* ps);//顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);//在pos位置前插入元素
void SeqListInsert(SeqList* ps, int pos, SLDateType x);//删除pos位置的值
void SeqListErase(SeqList* ps, int pos);//检查容量
void SeqListCheckCapacity(SeqList* ps);
二、实现思路
画图理解起来更佳!!!
1.存储结构
我们重命名int类型为SLDataType,方便以后我们修改顺序表存储元素的类型。
指针data指向动态开辟的空间,变量sz记录有效的数据元素,变量capacity记录动态开辟空间的大小。
typedef int SLDataType;typedef struct SeqList
{SLDataType* data;int sz;int capacity;
}SeqList;
2.初始化顺序表(SeqListInit)
动态开辟一块空间,用data指针保存空间首地址。
此时data指向空间中有效元素为0,使sz == 0,变量capacity在等于此时开辟空间的大小。
#define SIZE 4void SeqListInit(SeqList* ps)
{ps->data = (SLDataType*)malloc(sizeof(SLDataType) * SIZE);if (ps->data == NULL){perror("malloc");exit(-1);}ps->sz = 0;ps->capacity = SIZE;
}
3.销毁顺序表(SeqListDestroty)
free所开辟的空间,使data == NULL,此时数据有效元素为0,空间大小为0,那么sz = 0,capacity = 0;
//销毁顺序表
void SeqListDestroty(SeqList* ps)
{assert(ps);//free(ps);free(ps->data);ps->data = NULL;ps->sz = 0;ps->capacity = 0;
}
4.打印顺序表(SeqListPrint)
这个函数非常简单,只要遍历一遍所开辟的空间即可,注意范围是(0,sz)。
//打印顺序表
void SeqListPrint(SeqList* ps)
{assert(ps);for (int i = 0; i < ps->sz; i++){printf("%d ", ps->data[i]);}printf("\n");}
5.顺序表尾插(SeqListPushBack)and检查容量(SeqListCheckCapacity)
每次加入数据时,我们要先检查空间大小是否充足,再加入数据
-
检查容量
在尾插数据前,要检查空间大小是否充足(sz == capacity),如果空间大小不够,要扩大空间大小,capacity记录新的空间大小。 -
尾插元素
变量sz不仅代表空间有效元素个数,也代表了新数据元素将要放入的位置。所以尾插元素,只要空间大小充足,那么在data[sz]处放入数据即可,不要忘记sz要加一。
//检查容量
void SeqListCheckCapacity(SeqList* ps)
{SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc");exit(-1);}ps->data = tmp;ps->capacity *= 2;
}//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDataType x)
{assert(ps);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}ps->data[ps->sz] = x;ps->sz++;
}
6.顺序表头插(SeqLsitPushFront)
顺序表除了尾插,尾删不用挪到数据,其它的增删都要挪到数据。
头插数据,要先检查空间大小,再向后挪到数据,将数据放入data[0]处,sz在加一。
//顺序表头插
void SeqLsitPushFront(SeqList* ps, SLDataType x)
{assert(ps);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}int end = ps->sz;while (end > 0){ps->data[end] = ps->data[end - 1];end--;}ps->data[0] = x;ps->sz++;
}
7.顺序表尾删(SeqListPopBack)
变量sz代表有效数据的个数,那么只要sz减一,就代表最后一个数据被删除了。
//顺序表尾删
void SeqListPopBack(SeqList* ps)
{assert(ps);assert(ps->sz != 0);ps->sz--;
}
8.顺序表头删(SeqListPopFront)
头删数据,要将数据从后向前挪到,覆盖掉第一个数据,sz要减一。
//顺序表头删
void SeqListPopFront(SeqList* ps)
{assert(ps);assert(ps->sz != 0);for (int i = 0; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}
9.顺序表查找(SeqListFind)
遍历一遍动态开辟的数组,如果找到了就放回下标,没有就放回-1。
//顺序表查找
int SeqListFind(SeqList* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->sz; i++){if (ps->data[i] == x){return i;}}return -1;
}
10.在pos位置前插入元素(SeqListInsert)
要先检查空间容量是否充足和要插入的位置是否合法(要在顺序表的有效数据内),再将pos下标后的数据向后挪到,将数据放入data[pos]处,sz加一。
这个函数思路简单,但要注意下面两点:
- 如果pos == 0,不就是要在顺序表第一个元素前插入元素,不就是顺序表的头插。
- 如果pos == sz,我们知道sz还表示下一个数据要放入的位置,那么我在下一个数据要放入的位置前插入元素,不就是顺序表的尾插。
理解这点后,我们以后的头插,尾插都可以用该函数复用。方便我们手撕顺序表
//在pos位置前插入元素
void SeqListInsert(SeqList* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->sz);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}int end = ps->sz;while (end > pos){ps->data[end] = ps->data[end - 1];end--;}ps->data[pos] = x;ps->sz++;
}
11.删除pos位置的值(SeqListErase)
删除pos位置处的数据,先检查pos的合法性(要属于[0,sz-1]),要将数据从后向前挪到数据,sz减一。
这个函数思路简单,但要注意下面两点:
- 如果pos == 0,不就是要删除第一个数据,不就是头删。
- 如果pos == sz - 1,不就是要删除最后一个数据,不就是尾删。
所以对于尾删,头删函数而言,我们也可以使用该函数复用。
//删除pos位置的值
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->sz);for (int i = pos; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}
三、代码实现
头删,头插,尾删,尾插我都复用了SeqListInsert和SeqListErase。
SeqList.h 文件存放有关函数的声明以及结构体的声明
SeqList.c 文件存放函数的定义
//SeqList.h 文件#pragma once#include <stdio.h>
#include <stdlib.h>
#include <assert.h>#define SIZE 4typedef int SLDataType;typedef struct SeqList
{SLDataType* data;int sz;int capacity;
}SeqList;//初始化顺序表
void SeqListInit(SeqList* ps);//销毁顺序表
void SeqListDestroty(SeqList* ps);//打印顺序表
void SeqListPrint(SeqList* ps);//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDateType x);//顺序表头插
void SeqLsitPushFront(SeqList* ps, SLDateType x);//顺序表尾删
void SeqListPopBack(SeqList* ps);//顺序表头删
void SeqListPopFront(SeqList* ps);//顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);//在pos位置前插入元素
void SeqListInsert(SeqList* ps, int pos, SLDateType x);//删除pos位置的值
void SeqListErase(SeqList* ps, int pos);//检查容量
void SeqListCheckCapacity(SeqList* ps);
//SeqList.c 文件#include "SeqList.h"//初始化顺序表
void SeqListInit(SeqList* ps)
{ps->data = (SLDataType*)malloc(sizeof(SLDataType) * SIZE);if (ps->data == NULL){perror("malloc");exit(-1);}ps->sz = 0;ps->capacity = SIZE;
}//检查容量
void SeqListCheckCapacity(SeqList* ps)
{SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc");exit(-1);}ps->data = tmp;ps->capacity *= 2;
}//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDataType x)
{/*assert(ps);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}ps->data[ps->sz] = x;ps->sz++;*/SeqListInsert(ps, ps->sz, x);
}//打印顺序表
void SeqListPrint(SeqList* ps)
{assert(ps);for (int i = 0; i < ps->sz; i++){printf("%d ", ps->data[i]);}printf("\n");}//销毁顺序表
void SeqListDestroty(SeqList* ps)
{assert(ps);//free(ps);free(ps->data);ps->data = NULL;ps->sz = 0;ps->capacity = 0;
}//顺序表头插
void SeqLsitPushFront(SeqList* ps, SLDataType x)
{/*assert(ps);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}int end = ps->sz;while (end > 0){ps->data[end] = ps->data[end - 1];end--;}ps->data[0] = x;ps->sz++;*/SeqListInsert(ps, 0, x);
}//顺序表尾删
void SeqListPopBack(SeqList* ps)
{/*assert(ps);assert(ps->sz != 0);ps->sz--;*/SeqListErase(ps, ps->sz - 1);
}//顺序表头删
void SeqListPopFront(SeqList* ps)
{/*assert(ps);assert(ps->sz != 0);for (int i = 0; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;*/SeqListErase(ps, 0);
}//顺序表查找
int SeqListFind(SeqList* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->sz; i++){if (ps->data[i] == x){return i;}}return -1;
}//在pos位置前插入元素
void SeqListInsert(SeqList* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->sz);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}int end = ps->sz;while (end > pos){ps->data[end] = ps->data[end - 1];end--;}ps->data[pos] = x;ps->sz++;
}//删除pos位置的值
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->sz);for (int i = pos; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}
总结
以上就是顺序表的实现。谢谢支持!!!

相关文章:
数据结构:顺序表(C实现)
个人主页 水月梦镜花 个人专栏 C语言 ,数据结构 文章目录 一、顺序表二、实现思路1.存储结构2.初始化顺序表(SeqListInit)3.销毁顺序表(SeqListDestroty)4.打印顺序表(SeqListPrint)5.顺序表尾插(SeqListPushBack)and检查容量(SeqListCheckCapacity)6.顺序表头插(Se…...
素描基础知识
素描基础入门 1.基础线条 1.1 握笔姿势及长线条 2.排线 2.1 不同姿势画排线 2.1.1 姿势画排线 2.1.2 用手腕画排线 2.1.3 小拇指画排线 2.1.4 叠加排线 2.1.5交叉排线 2.2 纸张擦法 2.3 排线学习榜样 2.4 四种常见的排线 3、定向连线 4、一点透视 4.1 透视的规律 4.2 焦点透视…...
【Chat GPT】用 ChatGPT 运行 Python
前言 ChatGPT 是一个基于 GPT-2 模型的人工智能聊天机器人,它可以进行智能对话,同时还支持 Python 编程语言的运行,可以通过 API 接口进行调用。本文将介绍如何使用 ChatGPT 运行 Python 代码,并提供一个实际代码案例。 ChatGPT …...
cartographer发布畸变矫正后的scan数据
实现方式: 模仿源代码,在cartographer_ros写一个函数,以函数指针的方式传入cartographer后端,然后接收矫正后的scan数据,然后按照话题laserScan发布出来。 需要同时发布点云强度信息的,还要自己添加含有强度…...
Idea中git push to origin/master was rejected错误解决方案
Idea中git push to origin/master was rejected错误解决方案 问题描述解决方法 问题描述 idea开发中,需要将项目发布到gitee上,在gitee上创建仓库后,通过idea中git推送项目代码提示: push to origin/master was rejected 解决方法 gitee创建仓库时创建了README.md文件,本地…...
docker版jxTMS使用指南:自定义频率型动态管控
本文讲解4.4版jxTMS中如何自行定义一个频率型的动态管控,整个系列的文章请查看:docker版jxTMS使用指南:4.4版升级内容 docker版本的使用,请查看:docker版jxTMS使用指南 4.0版jxTMS的说明,请查看ÿ…...
【Docker】初识Docker以及Docker安装与阿里云镜像配置
目录 一、初识Docker 二、安装Docker 三、Docker架构 四、配置Docker镜像加速器 一、初识Docker Docker是一个开源的应用容器引擎,诞生于2013年,基于Go语言实现,dotCloud公司出品,Docker开源让开发者打包他们的应用以及依赖包到…...
C语言:动态内存管理
文章目录 一、动态内存函数1. malloc2. calloc3. realloc4. free 二、常见的错误1.malloc或calloc开辟的空间未检查2.越界访问3.对非malloc和calloc开辟的空间,用free释放4.对同一块动态内存多次释放5.用free释放动态内存的一部分 三、通讯录(动态版本改写)总结 一、…...
如何往MySQL中插入100万条数据?
需求 现在有一个 数据量 为100万的数据样本 100w_data.sql 其数据格式如下,截取最后十条数据 999991,XxGdnLZObA999991,XxGdnLZObA,XxGdnLZObA,2020-3-18,1 999992,TBBchSKobC999992,TBBchSKobC,TBBchSKobC,2020-9-8,2 999993,rfwgLkYhUz999993,rfwgLkYhUz,rfwgLk…...
IntelliJ IDEA 2023.2 最新变化
主要更新 AI Assistant 限定访问 Ultimate 在此版本中,我们为 IntelliJ IDEA 引入了一项重要补充 – AI Assistant。 AI Assistant 当前具备一组由 AI 提供支持的初始功能,提供集成式 AI 聊天,可以完成一些任务,例如自动编写文档…...
1300*B. T-primes
解析: 有且只有三个因数,当且仅当,完全平方数并且sqrt(n)为素数 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N1e55; ll t,n; bool prime(ll x){if(x<2) return 0;for(int…...
重新C++系列之运算符重载
一、什么是运算符重载 简单来讲就是对运算符赋予新的意义,但是又不能改变原有的含义,它本身也就是一个函数。运算符重载的本质是以函数的方式来体现。 二、运算符重载有几种 1、按照作用域来划分,有全局操作符重载函数和成员函数操作符重载函…...
kotlin异常处理try-catch-finally
kotlin异常处理try-catch-finally fun main(args: Array<String>) {try {println("a")} catch (e: Exception) {//异常捕获println("a-catch: $e")} finally {//善后,无论是否异常,都会执行println("a-finally")}t…...
Pytorch在cuda、AMD DirectML和AMD CPU下性能比较
一、测试环境 CUDA环境: i7-8550u 16G DDR4 2133MHz nVidia MX150 2GB AMD DirectML环境: Ryzen 5 5600G 32G DDR4 3200MHz Vega7 4GB AMD 纯CPU环境:Ryzen 5 5600G 32G DDR4 3200MHz 其他硬件配置的硬盘、电源均一致。Pytorch版本为2.0.0,Pyt…...
哈工大计算机网络课程局域网详解之:交换机概念
哈工大计算机网络课程局域网详解之:交换机概念 文章目录 哈工大计算机网络课程局域网详解之:交换机概念以太网交换机(switch)交换机:多端口间同时传输交换机转发表:交换表交换机:自学习交换机互…...
Jenkins Pipeline的hasProperty函数
函数的作用 用于判断某个参数或者字段是否存在。 用法 例子一 def projectStr "P1,P2,P3" pipeline {agent anyparameters {extendedChoice(defaultValue: "${projectStr}",description: 选择要发布的项目,multiSelectDelimiter: ,,name: SELECT_PROJ…...
芯片制造详解.净洁室的秘密.学习笔记(三)
这是芯片制造系列的第三期跟学up主三圈,这里对其视频内容做了一下整理和归纳,喜欢的可以看原视频。 芯片制造详解03: 洁净室的秘密|为何芯片厂缺人? 芯片制造详解.净洁室的秘密.学习笔记 三 简介一、干净的级别二、芯片…...
可解释的 AI:在transformer中可视化注意力
Visualizing Attention in Transformers | Generative AI (medium.com) 一、说明 在本文中,我们将探讨可视化变压器架构核心区别特征的最流行的工具之一:注意力机制。继续阅读以了解有关BertViz的更多信息,以及如何将此注意力可视化工具整合到…...
k8s Webhook 使用java springboot实现webhook 学习总结
k8s Webhook 使用java springboot实现webhook 学习总结 大纲 基础概念准入控制器(Admission Controllers)ValidatingWebhookConfiguration 与 MutatingWebhookConfiguration准入检查(AdmissionReview)使用Springboot实现k8s-Web…...
JS逆向之猿人学爬虫第20题-wasm
文章目录 题目地址sign参数分析python算法还原往期逆向文章推荐题目地址 https://match.yuanrenxue.cn/match/20第20题被置顶到了第1页,题目难度 写的是中等 算法很简单,就一个标准的md5算法,主要是盐值不确定, 而盐值就在wasm里面,可以说难点就在于wasm分析 sign参数分…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
算法刷题-回溯
今天给大家分享的还是一道关于dfs回溯的问题,对于这类问题大家还是要多刷和总结,总体难度还是偏大。 对于回溯问题有几个关键点: 1.首先对于这类回溯可以节点可以随机选择的问题,要做mian函数中循环调用dfs(i&#x…...
window 显示驱动开发-如何查询视频处理功能(三)
D3DDDICAPS_GETPROCAMPRANGE请求类型 UMD 返回指向 DXVADDI_VALUERANGE 结构的指针,该结构包含特定视频流上特定 ProcAmp 控件属性允许的值范围。 Direct3D 运行时在D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为特定视频流的 ProcAmp 控件属性指定DXVADDI_QUER…...
实现p2p的webrtc-srs版本
1. 基本知识 1.1 webrtc 一、WebRTC的本质:实时通信的“网络协议栈”类比 将WebRTC类比为Linux网络协议栈极具洞察力,二者在架构设计和功能定位上高度相似: 分层协议栈架构 Linux网络协议栈:从底层物理层到应用层(如…...
