你真的会数据结构吗:顺序表

❀❀❀ 文章由@不准备秃的大伟原创 ❀❀❀

♪♪♪ 若有转载,请联系博主哦~ ♪♪♪

❤❤❤ 致力学好编程的宝藏博主,代码兴国!❤❤❤

         又和大家见面啦!在大家看到这个标题的时候其实就已经发现了:我们的C语言的基础知识大部分已经学完了呢~真厉害,给自己鼓个掌吧,啪叽啪叽~ 现在开始我们要进击数据结构了!是不是很激动呢?诶,先憋激动,在开始前我们先了解一下数据结构是什么吧!

          我们在生活中无论什么事几乎都少不了逻辑吧,比如是先吃饭还是先睡觉,是先给大伟的文章点赞还是先收藏一下(^▽^ ),再更具体一点,我们的手机软件,比如电话啊,QQ啊,微信啊,里面不是都有联系人吗,我们可以在手机上对联系人进行一系列操作:修改信息,增加联系人,删除联系人,查找联系人等等等等.......这些啊其实都是我们的数据结构。

        而概念性来说:

数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的 数据元素的集合。

        我爱说实话,数据结构是非常非常重要的!无论是我们刷题目,以后面试,甚至是以后工作了之后,数据结构都是会一直会陪伴我们的,而大伟我也会一直陪着大家的(✿◡‿◡)

        那我们要如何学好数据结构呢?简单,像这样就行:b97051f1ef1e4e8191f898504d3e17a6.png

        哈哈,开个玩笑,别当真啦!其实呢,重要的是需要画图思考,虽然这两点在哪里都很重要就是了~

        好的,废话不多说,那我们就开始今天的内容:顺序表吧!

                顺序表

        在动手写码顺序表前,我们需要先来分清楚两个概念:线性表和顺序表:

        那有铁汁好奇了,线性表是啥呢?

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

        简单来说,线性表就是在逻辑上是一条线,而实际的物理结构不一定是一条线。而我们今天要写的顺序表就是一个线性表,且他的底层就是数组,是对数组进行了封装。

         谈到顺序表,我们就有两个选择:静态顺序表和动态顺序表。那么这两个有什么区别呢?我们通过代码来看一看:

静态:

typedef int SQLDataType;//重命名int
#define N 10
typedef struct SeqList {SQLDataType arr[N];int size;//顺序表的实际大小
}SeqList;//重命名结构体

        动态: 

typedef int SQLDataType;
typedef struct SeqList {SQLDataType *arr;int size;int capacity;
}SeqList;

        不知道大家还记不记得typedef了,没错,typedef将int 和 struct SeqList进行重命名,而我为什么要这么做呢?大家可以思考一下,其实也就是typedef的好处是什么:


        鸡屁踢老弟给出了以下几种答案:

  1. 代码可读性:为复杂的数据类型创建简洁的别名,提高代码的可读性
  2. 平台无关性:在一些情况下,数据类型的大小可能因编译器和操作系统的不同而有所变化,可以为不同平台定义相同的别名,提高代码的可移植性
  3. 简化复杂声明:声明一个函数指针类型可能会变得更加清晰
  4. 抽象底层实现:使你的代码更容易维护。通过定义数据类型的别名,你可以在不影响代码其他部分的情况下更改底层实现
  5. 提高代码的一致性:确保在整个代码库中一致地使用相同的数据类型,减少错误和混淆的可能性

        umm,说的很好,不亏是鸡踢屁牢弟,简单来说,就是便于书写和阅读,可以以便后面根据需求修改类型,如可以直接把一大片的int改为char,且便于维护。

        那我们再回到上面的两段代码,我们会发现,静态顺序表是通过N来确定整个顺序表的最大容积;而动态顺序表是定义了个指针,后期可以通过动态内存开辟来实现最大容积的变化,还有size来确定有效数据,capacity来确定最大数据。

        这样一对比铁汁们就会发现哪个方法会更好呢?  当然是动态更好了,对吧?

        好的,我们确定了我们的顺序表是由动态开辟的,那我们可以玩(对动态表做什么)什么呢?

        来,让我们联想到微信联系人,我们可以加小姐姐的wx(增),可以删掉不喜欢的基佬(删),查找自己的好舍友(查),修改新加的朋友的备注(改)。诶~对了,我们实现的就是增删查改。

        代码实现:

    和之前的扫雷一样,我们还是开了三个文件,分别为:Sql.c  Sql.h test.c(当然了,名字是自己取的,我这么取的原因是顺序表英文为Sequence List,这样子更容易理解)

        这里插一嘴啊~ 其实关于C语言的命名有一定的规则,如:大驼峰命名法等,有兴趣的铁汁们下来自己查啊~(ง •_•)ง

        首先我们先定义个结构体(Sql.h),当然了别忘了重命名:

#include<stdio.h>
#include<assert.h>
#include<malloc.h>
typedef int SQLDataType;
typedef struct SeqList {SQLDataType *arr;//数组保存数据int size;//有效数据体积int capacity;//最大体积
}SeqList;

        然后是我们的声明增删查改(Sql.h),但是在此之外我们还多了一些操作:

//顺序表初始化
void SeqListInit(SeqList* ps);
//检查空间,如果满了,进行增容
void CheckCapacity(SeqList* ps);
// 顺序表尾插
void SeqListPushBack(SeqList* ps, SQLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* ps);
// 顺序表头插
void SeqListPushFront(SeqList* ps, SQLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* ps);
// 顺序表查找
int SeqListFind(SeqList* ps, SQLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, size_t pos, SQLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* ps);
// 顺序表打印
void SeqListPrint(SeqList* ps);

         因为一开始只是一张白纸,所以初始化一下没问题吧,既然都初始化了,没有空间怎么可以呢,再来个检查空间也没问题吧,增的话,在头部增加,在尾部增加,在特定位置增加没话说吧,删的话,删头,删为,删特定位置也没话说吧,查找,修改,再打印个链表以便观察,最后再销毁,有始有终,完美!

        好,开码!

        Sql.c

初始化:

void SeqListInit(SeqList* ps)
{ps->arr = NULL;//一开始啥都没有ps->capacity = ps->size = 0;//一开始啥都没有
}

  检查空间:

void CheckCapacity(SeqList* ps)
{if (ps->capacity == ps->size)//若有效容积等于最大容积了{int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//若顺序表为空,先给四个空间,若不为空,两倍空间SQLDataType* tmp = (SQLDataType*)realloc(ps->arr, newCapacity * sizeof(SQLDataType));//扩容(开辟空间)if (tmp == NULL)//若开辟失败{perror("malloc failed!");return;}ps->arr = tmp;//修改空间ps->capacity = newCapacity;//修改最大体积}
}

  头插:

void SeqListPushFront(SeqList* ps, SQLDataType x)
{assert(ps);//断言,若ps不为空CheckCapacity(ps);//检查体积够不够了for (int i = ps->capacity; i > 0; i--){ps->arr[i] = ps->arr[i - 1];//从最后一个元素的后一个元素往前覆盖,直到第一个元素}ps->arr[0] = x;//修改首元素的值ps->size++;//修改size的值
}

尾插:

void SeqListPushBack(SeqList* ps, SQLDataType x)
{assert(ps);CheckCapacity(ps);ps->arr[ps->size] = x;//直接在最后一个有效元素有一个位置插入ps->size++;//修改size大小
}

特定位置插入:

void SeqListInsert(SeqList* ps, size_t pos, SQLDataType x)
{assert(ps);assert(pos >= 0 && pos < ps->size);//确保pos(下标)位置有效CheckCapacity(ps);for (int i = ps->size; i > pos ; i--){ps->arr[i] = ps->arr[i - 1];//从最后一个元素后面一个元素开始往前覆盖,直到下标为pos位置}ps->arr[pos] = x;//修改pos位置的值ps->size++;//修改size
}

头删:

void SeqListPopFront(SeqList* ps)
{assert(ps);int i;for ( i = 0; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];//从前往后一次覆盖}ps->arr[i] = -1;//将最后一个元素修改为-1(这句代码其实可以不需要,放上去也有问题,大家思考一下为什么)ps->size--;//修改size
}

尾删:

void SeqListPopBack(SeqList* ps)
{assert(ps);ps->arr[ps->size - 1] = -1;//(同样的,这句代码可以有问题并可以不要)ps->size--;//修改size
}

特定位置删除:

void SeqListErase(SeqList* ps, size_t pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);int i;for ( i = pos; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];//从pos位置往后,依次覆盖}ps->arr[i] = -1;//(多余,错误)ps->size--;//修改size
}

查找:

int SeqListFind(SeqList* ps, SQLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x)return i;//遍历,如果找到了,返回下标}return -1;//如果找不到,返回个无效的下标
}

打印:

void SeqListPrint(SeqList* ps)
{for (int i = 0; i < ps->size; i++){printf("%d  ", ps->arr[i]);//遍历一下,没啥好说的}printf("\n");
}
void SeqListDestory(SeqList* ps)
{assert(ps);free(ps->arr);//释放空间ps->arr = 0;ps->capacity = ps->size = 0;
}

        OK,OK,上面就是我们的的动态单链表的代码实现,现在考验大家的大家的记性和认真程度了:还记得博主括号内的问题吗?不记得?呵,赶紧回去看!o( ̄ε ̄*)  。昂,看到了吧?简单来说问题就是 ps->arr[i] = -1 为什么有问题,为什么可以不需要?

        emm,怎么说捏,我们在插入数据的时候范围是不限的吧,所以我们也可以插入一个-1进去吧?那如果我们现在把这个位置设置为-1,那可不可以算是插入了个-1呢?’(°ー°〃),所以,我们完全可以直接不给他赋值,任由他自由,反正我们后面也不要关心他的值对吧~?

        所以啊,我们的代码实现可以多种多样,逻辑上和实用性上都要考虑。那我们顺序表的代码写完了,不得来玩一玩?┗|*`0′*|┛

test.c

#include"Sql.h"
int main()
{SeqList ps;SeqListInit(&ps);SeqListPushBack(&ps, 1);SeqListPushBack(&ps, 2);SeqListPushBack(&ps, 3);SeqListPushBack(&ps, 4);SeqListPrint(&ps);//1 2 3 4SeqListPushFront(&ps, 7);SeqListPushFront(&ps, 6);SeqListPushFront(&ps, 5);SeqListPrint(&ps);//5 6 7 1 2 3 4 SeqListPopBack(&ps);SeqListPopBack(&ps);SeqListPrint(&ps);//5 6 7 1 2SeqListPopFront(& ps);SeqListPopFront(&ps);SeqListPrint(&ps);// 7 1 2if (SeqListFind(&ps, 1))printf("1的下标为%d\n", SeqListFind(&ps, 1));elseprintf("找不到!");//1的下标为1SeqListInsert(&ps, 1, 5);SeqListPrint(&ps);// 7 5 1 2SeqListErase(&ps, 2);SeqListPrint(&ps);// 7 5 2SeqListDestory(&ps);SeqListPrint(&ps);//NULLreturn 0;
}

        让我们看看运行框内打印的是不是和我们想要的一样呢?5081831b6f96458e9178843f0761a0cd.png

        通过对比,我们发现实际输出的结果和我们想要的效果完全一样啊,而且代码返回为0,这也就说明了我们代码写的没有问题。

        害,累鼠博主了,看到这里还不给大伟来个一键三连?o(^▽^)o。今天的顺序表也就到此为止了啊,下次带大家来看看顺序表的实际应用~期待着吧!

        I have no secret of success but hard work. 除辛勤工作之外,我别无成功的秘诀。

        本篇博客也就到此为止了,送大家一碗鸡汤,勉励自己以及这世界上所有追逐梦想的赤子趁年华尚好努力提升自己,莫欺少年穷!          fb28922170e04390ad2f6e3e4a3856be.jpeg

 

 

 

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

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

相关文章

【GitHub项目推荐--不错的 Go开源项目】【转载】

开源实时性能分析平台 Pyroscope 是基于 Go 的开源实时性能分析平台&#xff0c;在源码中添加几行代码 pyroscope 就能帮你找出源代码中的性能问题和瓶颈、CPU 利用率过高的原因&#xff0c;调用树展示帮助你理解程序&#xff0c;支持 Go、Python、Ruby 语言。 Pyroscope 可以…

java程序判等问题

注意 equals 和 的区别 对基本类型&#xff0c;比如 int、long&#xff0c;进行判等&#xff0c;只能使用 &#xff0c;比较的是直接值。因为基本类型的值就是其数值。对引用类型&#xff0c;比如 Integer、Long 和 String&#xff0c;进行判等&#xff0c;需要使用 equals 进…

智能解决方案——体脂秤芯片CSU18M91

现在的年轻人爱健身&#xff0c;十分关注身材、形体&#xff0c;减肥、健身成了生活日常&#xff1b;中老年人则关注健康指数、有无病症&#xff0c;实时把握身体情况。现在一台体脂称通过测试体重、体脂、BMI、水分等数据并给出相应提示&#xff0c;并且许多人都将体脂检测数据…

MySQL分组,获取组内最新的10条数据

一、记录 记录一次SQL&#xff0c;最近在项目中遇到了一个相对比较复杂的SQL。 要求依据分组&#xff0c;获取每个分组后的前10条数据。 分组查询最新的数据&#xff0c;应该都做过&#xff0c;但是获取前10条数据&#xff0c;还是没处理过的。 二、处理 2.1 前期数据准备 …

开发知识点-Flutter移动应用开发

支持 安卓 IOS Android 鸿蒙 第一章dart基础章节介绍 移动电商——Flutter-广告Banner组件制作 移动电商——Flutter实战课程介绍 Flutter实例——路由跳转的动画效果

Elment UI的el-table-column表头旁边有点击按钮类似的操作

Elment UI的el-table-column表头旁边有点击按钮类似的操作 <el-table-column fixed"right" label"操作" ><!-- 表头 --> {{-- <template slot"header" header"scope">--}} {{-- <span…

精通 VS 调试技巧,学习与工作效率翻倍!

​ ✨✨ 欢迎大家来到贝蒂大讲堂✨✨ ​ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; ​ 所属专栏&#xff1a;C语言学习 ​ 贝蒂的主页&#xff1a;Betty‘s blog 1. 什么是调试 当我们写代码时候常常会遇见输出结果不符合我们预…

单轴测径仪在线缆电缆测控中的应用

线缆电缆在生产中能进行品质测量与控制&#xff0c;对其生产模式而言&#xff0c;是更为合适的&#xff0c;毕竟其生产模式决定了其任何品质问题出现都会造成产品的品质下降或不合格。要想进行生产高品质的产品&#xff0c;对产线的要求较高。 单轴测径仪作为测控一体&#xff…

安卓开发之自动缩放布局

AutoScalingLayout 适用于 Android 的自动缩放布局。 替换布局&#xff1a; 我们只需要替换根布局所需的自动缩放&#xff0c;子布局也将实现自动缩放。 原始布局AutoScalingLayout相对布局ASRelativeLayout线性布局ASLinearLayoutFrameLayout&#xff08;框架布局&#xff…

项目一:踏上Java开发之旅

文章目录 一、实战概述二、实战步骤任务1&#xff1a;安装配置JDK并开发第一个Java程序步骤一&#xff1a;安装JDK步骤二&#xff1a;配置JDK环境变量步骤三&#xff1a;开发第一个Java程序 课堂练习任务1、打印个人信息任务2、打印直角三角形任务3、打印一颗爱心任务4、打印史…

Linux服务器系统修改SSH端口教程

修改端口号是通过修改SSH的配置文件实现的&#xff0c;在服务器终端先激活root用户&#xff0c;然后输入&#xff1a; vim /etc/ssh/sshd_config找到#Port 22这个位置 键盘按i进入编辑模式 删除掉Port 22前面的#&#xff0c;然后键盘按一下回车键&#xff08;如果没有#可不必…

记一次SPI机制导致的BUG定位【不支持:http://javax.xml.XMLConstants/property/accessExternalDTD】

1、前因 今天在生产环境启用了某个功能&#xff0c;结果发现有个文件上传华为云OBS失败了&#xff0c;报错如下&#xff1a; Caused by: java.lang.IllegalArgumentException: 不支持&#xff1a;http://javax.xml.XMLConstants/property/accessExternalDTDat org.apache.xal…

C++参悟:数值运算相关

数值运算相关 一、概述二、常用数学函数1. 基础运算1. 浮点值的绝对值&#xff08; |x| &#xff09;2. 浮点除法运算的余数3. 除法运算的有符号余数4. 除法运算的有符号余数和最后三个二进制位5. 混合的乘加运算6. 两个浮点值的较大者7. 两个浮点值的较小者8. 两个浮点值的正数…

Grafana loki配置, 无脑版

使用docker部署Grafana loki 1.创建 docker-compose.yml 文件 touch docker-compose.yml写入以下内容 vim touch docker-compose.yml version: "3"networks:loki:services:loki:image: grafana/loki:latestrestart: unless-stoppedports:- "3100:3100"vo…

LeetCode 14.最长公共前缀(python版)

需求 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例 1&#xff1a; 输入&#xff1a;strs [“flower”,“flow”,“flight”] 输出&#xff1a;“fl” 示例 2&#xff1a; 输入&#xff1a;strs [“dog”,“race…

【高效开发工具系列】Intellj IDEA 2023.3 版本

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

curl命令导致你下载的文件为空原因分析

文章目录 1.前言2. 通过curl -O 下载远端文件2.1 执行curl -O下载远端文件2.2 通过curl -v 查看详细的请求和响应的信息 3.通过在curl -O 中增加 -L 参数保证curl能够自动跟踪和请求远端返回的重定向地址4.结论 1.前言 最近在进行线上项目调试的过程中需要安装调试工具&#xf…

HubSpot能不能对接微信公众号?

在当今数字化时代&#xff0c;企业的数字化营销策略不可或缺。其中&#xff0c;HubSpot作为一体化营销平台&#xff0c;是否能与国内最大的社交平台之一——微信公众号进行无缝对接&#xff0c;成为业界关注的焦点。今天运营坛将深入探讨HubSpot与微信公众号的对接流程、Messag…

【华为 ICT HCIA eNSP 习题汇总】——题目集6

1、IEEE 802.11g 标准支持的最大协商速率为&#xff08;&#xff09;。 A、300Mbps B、150Mbps C、54Mbps D、1200Mbps 考点&#xff1a;无线局域网 解析&#xff1a;&#xff08;C&#xff09; IEEE 802.11系列标准如下表&#xff1a; 标准数据传输速率主要技术IEEE 802.111M…

【网站项目】医院管理系统源码(有源码)

🙊作者简介:多年一线开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板,帮助书写开题报告。作者完整代码目录供你选择: 《Springboot网站项目…