数据结构:顺序表(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参数分…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...