数据结构篇1—《顺序表》

在这里插入图片描述

文章目录

  • 🚩前言
    • 1. 数据结构的概念
    • 2. 数据结构的分类
    • 3. 顺序表
      • 3.1. 顺序表的分类
        • (1)静态顺序表
        • (2)动态顺序表
    • 4. 动态顺序表实现
      • 4.1. 实现步骤
        • (1)框架结构
        • (2)SeqList.h头文件实现
        • (3)SeqList.c源文件
          • ①init_seqlist()初始化函数
          • ②print_seqlist()打印函数
          • ③PushBack()尾插函数+图解
          • ④PushFront()头插函数+图解
          • ⑤PopBack()尾删函数+图解
          • ⑥PopFront()头删函数+图解
          • ⑦DeletePosition()删除指定位置函数
          • ⑧InsertPosition()指定位置插入数据函数
          • ⑨ModifyPosition()修改指定位置数据函数
          • ⑩FindPosition()查找函数
          • 🚀DestroyCapacity()销毁函数
    • 5. 完整代码

🚩前言

在前面的文章中,写了关于C语言的各种知识点,也许内容不是很精炼,但对后面知识的学习还是有必要的。接下来就是用C语言实现数据结构的编程。

1. 数据结构的概念

我们从词组来看,数据结构就是两者组成,一是数据,二是结构。数据指的就是各种能表示对象的内容,比如C语言中用各种数据类型来表示标量的事物,比如价格、体重等,还有C语言中的自定义类型来表示各种具体的对象,比如学生对象等,这些都是数据。而结构就是把这些数据按照一定的规则存储起来,让数据内容在计算机中能有一定顺序结构的存储。

2. 数据结构的分类

在这里插入图片描述

今天所讲的名字叫做顺序表,它是属于线性结构的,用顺序存储的方式。底层是数组。

3. 顺序表

说白了,顺序表的底层就是数组,对数组的封装,实现增删查改的API;

3.1. 顺序表的分类

(1)静态顺序表

结构体定义如下:

#define N 10;//宏定义,方便修改数组的大小
typedef int DataType;//数据类型取别名
typedef struct SeqList
{DataType elem[N];//此处就是一个整型数组,大小是固定的,定长数组。int size;//表示该数组中的有效个数。
}SL;//用typedef给struct SeqList取别名。
//在后面用到就不用写struct SeqList,直接写SL;

图解如下:
在这里插入图片描述
静态顺序表的缺点:空间给多了造成浪费、空间给少了不够用!

(2)动态顺序表

结构体定义如下:

typedef int DataType;//数据类型取别名
typedef struct SeqList
{DataType* elem;//此处变成指针,通过动态申请空间int capacity;//表示申请的空间总大小,空间是可以增容的int size;//表示该数组中的有效个数。
}SL;//用typedef给struct SeqList取别名。

图解如下:
在这里插入图片描述
动态的顺序表,就是要记住空间是动态申请的,到最后记得手动释放,free()释放函数

4. 动态顺序表实现

动态相比于静态的要复杂一点,此处就用动态的顺序表来详解。

4.1. 实现步骤

(1)框架结构

在这里插入图片描述

(2)SeqList.h头文件实现
#pragma once#include<stdio.h>
#include<assert.h>
#include<stdlib.h>#define INIT_SIZE 2//创建动态顺序表的结构体
typedef int DataType;
typedef struct SeqList
{DataType* elem;int capacity;int size;
}SL;//创建好后就初始化结构体
void init_seqlist(SL* sl);//初始化函数void print_seqlist(SL sl);//打印函数void PushBack(SL* sl, DataType data);//尾插函数void PushFront(SL* sl, DataType data);//头插函数void PopBack(SL* sl);//尾删函数void PopFront(SL* sl);//头删函数void InsertPosition(SL* ptr, int pos, DataType data);//指定位置插入数据函数void DeletePosition(SL* ptr, int pos);//删除指定位置的元素void ModifyPosition(SL* ptr, int pos, DataType data);//修改指定位置的数据int FindPosition(SL ptr, DataType data);//查找函数void DestroyCapacity(SL* ptr);//销毁函数

(3)SeqList.c源文件
①init_seqlist()初始化函数
//初始化函数
void init_seqlist(SL* sl)
{assert(sl);sl->elem = NULL;sl->capacity = sl->size=0;
}

调试结果:
在这里插入图片描述

我们可以在初始化的时候就分配空间,代码如下:

//初始化函数
#define INIT_SIZE 2void init_seqlist(SL* sl)
{assert(sl);sl->elem = (SL*)malloc(INIT_SIZE * sizeof(SL));sl->capacity = INIT_SIZE;sl->size = 0;
}

调试如下:
在这里插入图片描述


②print_seqlist()打印函数
//打印函数
void print_seqlist(SL sl)
{if (sl.size == 0){printf("顺序表内容为空,无法打印!\n");return;}for (int i = 0; i < sl.size; i++){printf("%d ",sl.elem[i]);}printf("\n");
}

由于打印函数不需要修改内容,所以不需要传递地址


③PushBack()尾插函数+图解
static check_capacity(SL* sl)
{assert(sl);//看空间里面实际的元素个数是否等于申请的空间大小,相等就说明满了;if (sl->capacity == sl->size){int new_capacity = sl->capacity == 0 ? 4 : 2 * sl->capacity;//以2倍数增容DataType* temp = (DataType*)realloc(sl->elem, new_capacity * sizeof(DataType*));if (temp == NULL){perror("realloc fail");exit(1);}//申请成功sl->elem = temp;sl->capacity = new_capacity;}
}//尾插函数
void PushBack(SL* sl, DataType data)
{assert(sl);//在插入的时候,必须判断空间是否满,是否需要扩容;check_capacity(sl);//插入数据sl->elem[sl->size++] = data;
}

结果展示:
在这里插入图片描述

尾插图解
在这里插入图片描述


④PushFront()头插函数+图解
//头插函数
void PushFront(SL* sl, DataType data)
{assert(sl);//插入之前也是需要检测空间的check_capacity(sl);//插入,移动元素,从后往前移动for (int i = sl->size; i > 0; i--){sl->elem[i] = sl->elem[i - 1];}//第一个空出来后插入数据sl->elem[0] = data;sl->size++;
}

结果展示:
在这里插入图片描述

头插图解:
在这里插入图片描述

⑤PopBack()尾删函数+图解
//尾删函数
void PopBack(SL* sl)
{assert(sl&&sl->size);//保证传入的空间有效和数据个数不为0//尾删sl->size--;
}

结果展示:
在这里插入图片描述

尾删图解:
在这里插入图片描述

⑥PopFront()头删函数+图解
//头删函数
void PopFront(SL* sl)
{assert(sl && sl->size);//头删for (int i = 0; i < sl->size - 1; i++){sl->elem[i] = sl->elem[i + 1];}sl->size--;
}

结果展示:
在这里插入图片描述

头删图解:
在这里插入图片描述

⑦DeletePosition()删除指定位置函数
//删除指定位置的元素
void DeletePosition(SL* sl, int pos)
{assert(sl && sl->size);		assert(pos >= 0 && pos < sl->size);for (int i = pos; i < sl->size; i++){sl->elem[i] = sl->elem[i + 1];}sl->size--;
}

结果展示:
在这里插入图片描述

图解:
在这里插入图片描述

⑧InsertPosition()指定位置插入数据函数
//指定位置插入数据函数
void InsertPosition(SL* sl, int pos, DataType data)
{assert(sl&&pos>=0&&pos<=sl->size);//先移动位置,往后移动//还得检查是否需要扩容check_capacity(sl);for (int i = sl->size; i > pos; i--){sl->elem[i] = sl->elem[i - 1];}//位置空出来之后就加入数据sl->elem[pos] = data;//记得元素个数+1sl->size++;
}

结果展示:
在这里插入图片描述

⑨ModifyPosition()修改指定位置数据函数
//修改指定位置的数据
void ModifyPosition(SL* sl, int pos, DataType data)
{assert(sl&&pos>=0&&pos<sl->size);//现找到修改数据的位置for (int i = 0; i < sl->size; i++){if (i == pos){//修改sl->elem[i] = data;}}
}

结果展示:
在这里插入图片描述

⑩FindPosition()查找函数
//查找函数
int FindPosition(SL sl, DataType data)
{if (sl.size == 0){printf("数据内容为空,无法查找!\n");exit(1);}for (int i = 0; i < sl.size; i++){if (sl.elem[i] == data){return i;}}return -1;
}

结果展示:
在这里插入图片描述

🚀DestroyCapacity()销毁函数
//销毁函数
void DestroyCapacity(SL* sl)
{if (sl->elem != NULL){free(sl->elem);}sl->elem = NULL;sl->capacity = sl->size = 0;
}

调试结果:
在这里插入图片描述

5. 完整代码

SeqList.h

#pragma once#include<stdio.h>
#include<assert.h>
#include<stdlib.h>#define INIT_SIZE 2//创建动态顺序表的结构体
typedef int DataType;
typedef struct SeqList
{DataType* elem;int capacity;int size;
}SL;//创建好后就初始化结构体
void init_seqlist(SL* sl);//初始化函数void print_seqlist(SL sl);//打印函数void PushBack(SL* sl, DataType data);//尾插函数void PushFront(SL* sl, DataType data);//头插函数void PopBack(SL* sl);//尾删函数void PopFront(SL* sl);//头删函数void InsertPosition(SL* sl, int pos, DataType data);//指定位置插入数据函数void DeletePosition(SL* sl, int pos);//删除指定位置的元素void ModifyPosition(SL* sl, int pos, DataType data);//修改指定位置的数据int FindPosition(SL sl, DataType data);//查找函数void DestroyCapacity(SL* sl);//销毁函数

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"//打印函数
void print_seqlist(SL sl)
{if (sl.size == 0){printf("顺序表内容为空,无法打印!\n");return;}for (int i = 0; i < sl.size; i++){printf("%d ",sl.elem[i]);}printf("\n");
}//初始化函数
void init_seqlist(SL* sl)
{assert(sl);sl->elem = NULL;sl->capacity = sl->size=0;/*assert(sl);sl->elem = (SL*)malloc(INIT_SIZE * sizeof(SL));sl->capacity = INIT_SIZE;sl->size = 0;*/
}static check_capacity(SL* sl)
{assert(sl);//看空间里面实际的元素个数是否等于申请的空间大小,相等就说明满了;if (sl->capacity == sl->size){int new_capacity = sl->capacity == 0 ? 4 : 2 * sl->capacity;//以2倍数增容DataType* temp = (DataType*)realloc(sl->elem, new_capacity * sizeof(DataType*));if (temp == NULL){perror("realloc fail");exit(1);}//申请成功sl->elem = temp;sl->capacity = new_capacity;}
}//尾插函数
void PushBack(SL* sl, DataType data)
{assert(sl);//在插入的时候,必须判断空间是否满,是否需要扩容;check_capacity(sl);//插入数据sl->elem[sl->size++] = data;
}//头插函数
void PushFront(SL* sl, DataType data)
{assert(sl);//插入之前也是需要检测空间的check_capacity(sl);//插入,移动元素,从后往前移动for (int i = sl->size; i > 0; i--){sl->elem[i] = sl->elem[i - 1];}//第一个空出来后插入数据sl->elem[0] = data;sl->size++;
}//尾删函数
void PopBack(SL* sl)
{assert(sl&&sl->size);//保证传入的空间有效和数据个数不为0//尾删sl->size--;
}//头删函数
void PopFront(SL* sl)
{assert(sl && sl->size);//头删for (int i = 0; i < sl->size - 1; i++){sl->elem[i] = sl->elem[i + 1];}sl->size--;
}//删除指定位置的元素
void DeletePosition(SL* sl, int pos)
{assert(sl && sl->size);assert(pos >= 0 && pos < sl->size);for (int i = pos; i < sl->size-1; i++){sl->elem[i] = sl->elem[i + 1];}sl->size--;
}//指定位置插入数据函数
void InsertPosition(SL* sl, int pos, DataType data)
{assert(sl&&pos>=0&&pos<=sl->size);//先移动位置,往后移动//还得检查是否需要扩容check_capacity(sl);for (int i = sl->size; i > pos; i--){sl->elem[i] = sl->elem[i - 1];}//位置空出来之后就加入数据sl->elem[pos] = data;//记得元素个数+1sl->size++;
}//修改指定位置的数据
void ModifyPosition(SL* sl, int pos, DataType data)
{assert(sl&&pos>=0&&pos<sl->size);//现找到修改数据的位置for (int i = 0; i < sl->size; i++){if (i == pos){//修改sl->elem[i] = data;}}
}//查找函数
int FindPosition(SL sl, DataType data)
{if (sl.size == 0){printf("数据内容为空,无法查找!\n");exit(1);}for (int i = 0; i < sl.size; i++){if (sl.elem[i] == data){return i;}}return -1;
}//销毁函数
void DestroyCapacity(SL* sl)
{if (sl->elem != NULL){free(sl->elem);}sl->elem = NULL;sl->capacity = sl->size = 0;
}

test.c

#define _CRT_SECUR_NO_WARNINGS 1
#include"SeqList.h"void test01()
{SL sl;init_seqlist(&sl);//此处记得传地址。//尾插PushBack(&sl, 1);PushBack(&sl, 2);PushBack(&sl, 3);PushBack(&sl, 4);print_seqlist(sl);//头插PushFront(&sl, 5);print_seqlist(sl);/*PushFront(&sl, 6);print_seqlist(sl);*/尾删//PopBack(&sl);//print_seqlist(sl);//PopBack(&sl);//print_seqlist(sl);//头删/*PopFront(&sl);print_seqlist(sl);PopFront(&sl);print_seqlist(sl);*///指定位置删除/*printf("删除下标为2的数据:\n");DeletePosition(&sl,2);print_seqlist(sl);*///指定位置插入数据/*printf("在下标为2的位置插入100数据:\n");InsertPosition(&sl,2,100);print_seqlist(sl);*/修改//printf("修改下标为3的数据:\n");//ModifyPosition(&sl,3,666);//print_seqlist(sl);//查找printf("查找数据为2的位置:\n");int ret=FindPosition(sl, 2);if (ret == -1){printf("没找到!\n");}else{printf("找到了,在下标为%d位置处!",ret);}DestroyCapacity(&sl);}int main()
{test01();//函数测试return 0;
}

顺序表内容到此为止,蟹蟹:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/812572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何准备2024年汉字小达人:18道历年考题示例和解析、备考提醒

现在距离2024年第11届汉字小达人比赛还有六个多月的时间&#xff0c;如何利用这段时间有条不紊地备考呢&#xff1f;我的建议是两手准备&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0c;重点是字、词、成语、古诗。阅读理解不需要。②把历年真题刷刷熟&#x…

linux如何使 CPU使用率保持在指定百分比?

目录 方法1&#xff1a;&#xff08;固定在100%&#xff09; 方法2&#xff1a;&#xff08;可以指定0~100%&#xff09; 方法3&#xff1a;使用ChaosBlade工具&#xff08;0~100%&#xff09; 方法1&#xff1a;&#xff08;固定在100%&#xff09; for i in seq 1 $(cat /pro…

vscode常用插件

1. chinese&#xff08;汉化编译器&#xff09; chinese插件适用于 VS Code 的中文&#xff08;简体&#xff09;语言包&#xff0c;此中文&#xff08;简体&#xff09;语言包为 VS Code 提供本地化界面。 2、vetur&#xff08;vue 2开发必备&#xff09;volar&#xff08;vu…

【Jenkins】Jenkins自动化工具介绍

目录 技术背景常规的手动打包步骤 Jenkins简介起源与发展Jenkins的核心价值1.自动化1.1代码构建1.2测试自动化1.3自动部署 2.持续集成与持续部署CI/CD的概念如何减少集成问题更快速地发布软件版本 Jenkins优势Jenkins的主要竞争对手Travis CI:CircleCI:GitLab CI: Jenkins与其他…

SpringBoot之集成Redis

SpringBoot之集成Redis 一、Redis集成简介二、集成步骤2.1 添加依赖2.2 添加配置2.3 项目中使用 三、工具类封装四、序列化 &#xff08;正常都需要自定义序列化&#xff09;五、分布式锁&#xff08;一&#xff09;RedisTemplate 去实现场景一&#xff1a;单体应用场景二&…

vim卡死了,没有反应怎么办?

解决办法&#xff1a; 很有可能是你有个在window下的好习惯&#xff0c;没事儿就ctrl s保存文件。但是在vim里&#xff0c;ctrl s默认是发送一种流控制信号&#xff0c;通常用于停止终端的输出&#xff0c;所以你的屏幕就卡死了。 解决办法也很简单&#xff0c;按下ctrl q即…

NJU PA0

NJU PA0 使用教程提供的源再进行sudo apt install … 可能会出现 Unmet dependencies 此类报错 可以安装 aptitude sudo apt install aptitude sudo aptitude install <package>然后它会提示你&#xff0c;选 n 进行降级。再选 Y 确认 或者 将 /etc/apt/sources.list 下…

【c++】优先级队列|反向迭代器(vector|list)

优先级队列的常用函数的使用 #include<iostream> #include<queue> using namespace std;int main() {priority_queue<int>st;st.push(1);st.push(7);st.push(5);st.push(2);st.push(3);st.push(9);while (!st.empty()){cout << st.top() << &qu…

UDP简单总结

UDP&#xff1a;用户数据报协议 特点: 无连接、不可靠通信 不事先建立连接&#xff0c;数据按照包发&#xff0c;一包数据包含&#xff1a;自己的IP、程序端口、目的地IP、程序端口和数据(限制在64KB内) 发送方不管对方是否在线&#xff0c;数据在中间丢失也不管&#xff0c;…

SpringBoot与MyBatisPlus的依赖版本冲突问题

记录使用SpringBoot和MyBatisPlus时遇到的版本冲突问题解决。 java版本&#xff1a;jdk17 废话&#xff1a;&#xff09;目前在IDEA中使用Spring官方的脚手架最低jdk版本竟然是jdk17了。 当使用SpringBoot3.0版本(3.2.4)&#xff0c;配合使用MP3.5.2版本时报错&#xff1a; Er…

对于所有对象都通用的方法⭐良好习惯总结

对于所有对象都通用的方法⭐良好习惯总结 Object是每个类的父类&#xff0c;它提供一些非final方法&#xff1a;equals、hashCode、clone、toString、finalize... 这些方法在设计上是可以被子类重写的&#xff0c;但是重写前需要遵守相关的规定&#xff0c;否则在使用时就可能…

应用实战|从头开始开发记账本2:基于模板快速开始

上期视频我们创建好了BaaS服务的后端应用。从这期视频开始&#xff0c;我们将从头开发一个互联网记账本应用。本期视频我们介绍一下如何使用模板快速开启我们的应用开发之旅。 应用实战&#xff5c;从头开始开发记账本2&#xff1a;基于模板快速开始 相关代码 本期视频我们介绍…

RestTemplate—微服务远程调用—案例解析

简介&#xff1a;总结来说&#xff0c;微服务之间的调用方式有多种&#xff0c;选择哪种方式取决于具体的业务需求、技术栈和架构设计。RESTful API和HTTP客户端是常见的选择&#xff0c;而Feign和Ribbon等辅助库可以简化调用过程。RPC和消息队列适用于特定的场景&#xff0c;如…

《由浅入深学习SAP财务》:第2章 总账模块 - 2.6 定期处理 - 2.6.4 月末操作:货币折算

2.6.4 月末操作&#xff1a;货币折算 如果一个公司代码启用了多个本位币&#xff0c;如下表所示&#xff0c;则在平时记账时&#xff0c;系统会在凭证行项目中同时体现出多个本位币的金额。 图2.6.4-1 两个本位币的金额都会实时更新到科目余额中。因此&#xff0c;在月末可以直…

pycharm2024关闭项目后一直显示正在关闭项目

网上的很多教程都试了不行&#xff0c;直接用下面的方法有效解决。 点击 帮助--查找操作--输入Registry--点注册表&#xff0c;取消ide.await.scope.completion后的勾选即可。

武汉星起航:跨境电商势头强劲,开启外贸增长新纪元

在全球化浪潮的推动下&#xff0c;跨境电商作为新兴贸易方式&#xff0c;正以前所未有的速度崛起。2024年前两个月&#xff0c;跨境电商进出口增长近10%&#xff0c;这一令人瞩目的数据&#xff0c;不仅彰显出跨境电商的强劲发展势头&#xff0c;更预示着其作为外贸新增长极的潜…

直接扩展到无限长,谷歌Infini-Transformer终结上下文长度之争

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 不知 Gemini 1.5 Pro 是否用到了这项技术。 谷歌又放大招了&#xff0c;发布下一代 Transfor…

突破像素限制,尽显照片细腻之美——Topaz Gigapixel AI for Mac/Win

在这个数字化的时代&#xff0c;我们都热爱用照片记录生活中的美好瞬间。然而&#xff0c;有时候我们会发现&#xff0c;由于各种原因&#xff0c;照片的像素可能无法满足我们的需求。这时候&#xff0c;Topaz Gigapixel AI for Mac/Win 这款强大的照片放大工具应运而生。 Top…

联储降息预期落空打了谁的脸

美国 3 月消费者价格指数&#xff08;CPI&#xff09;于本周发布&#xff0c;最新数据全线高于预期。具体而言&#xff0c;美国劳工部周三公布的数据显示&#xff0c;美国 3 月消费者物价指数&#xff08;CPI&#xff09;同比上涨 3.5%&#xff0c;为 2023 年 9 月以来最高水平…

python基础——类【类的定义和使用、魔术方法】

&#x1f4dd;前言&#xff1a; python中的类&#xff0c;自我感觉在某种程度上和C语言的结构体是有共同之处的&#xff0c;如果有兴趣&#xff0c;可以先看看这篇文章&#xff1a;C语言——结构体类型&#xff08;一&#xff09;&#xff0c;先了解一下C语言中的结构体&#x…