【数据结构】【版本1.0】【线性时代】——顺序表



快乐的流畅:个人主页


个人专栏:《算法神殿》《数据结构世界》《进击的C++》

远方有一堆篝火,在为久候之人燃烧!

文章目录

  • 引言
  • 一、顺序表的概念
    • 1.1 最基础的数据结构:数组
    • 1.2 数组与顺序表的区别
  • 二、静态顺序表
  • 三、动态顺序表的模拟实现
    • 3.1 定义
    • 3.2 初始化
    • 3.3 销毁
    • 3.4 扩容
    • 3.5 尾插
    • 3.6 头插
    • 3.7 尾删
    • 3.8 头删
    • 3.9 指定插入
    • 3.10 指定删除
    • 3.11 查找
    • 3.12 修改
    • 3.13 打印

引言

数据结构世界——顺序表(Sequential List)

一、顺序表的概念

1.1 最基础的数据结构:数组

【思考】有了数组,为什么还要学习其他的数据结构?

假定数组有10个空间,已经使用了5个,向数组中插入数据步骤:求数组的长度,求数组的有效数据个数,向下标为数据有效个数的位置插入数据(注意:这里是否要判断数组是否满了,满了还能继续插入吗)…


假设数据量非常庞大,频繁的获取数组有效数据个数会影响程序执行效率。

结论:最基础的数据结构能够提供的操作已经不能完全满足复杂算法实现

1.2 数组与顺序表的区别

顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口。

二、静态顺序表

//静态顺序表
#define N 10
typedef int SLDataType;typedef struct SeqList
{SLDataType a[N];int size;
}SL;

​​​​

静态顺序表缺陷空间给少了不够用,给多了造成空间浪费

三、动态顺序表的模拟实现

3.1 定义

//动态顺序表
typedef int SLDataType;typedef struct SeqList
{SLDataType* a;int size;//存储的有效数据的个数int capacity;//容量
}SL;

顺序表的各种功能,都是通过函数来实现的。

3.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;
}
  • 函数参数传结构体指针,这样才能在函数内部对顺序表进行各种解引用操作
  • 对于动态顺序表,初始化则用malloc函数动态开辟内存空间 ;存储个数为0,容量初始置为4

3.3 销毁

void SLDestroy(SL* psl)
{assert(psl);free(psl->a);psl->a = NULL;psl->size = 0;psl->capacity = 0;
}
  • 对于用free函数将动态开辟的空间进行释放,并将指针置为NULL ;再将存储个数和容量置为0

3.4 扩容

数组满了怎么办?那么,我们就需要扩容,定义一个函数专门来检测容量,如果容量满了,则进行扩容。

static void CheckCapacity(SL* psl)
{assert(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;}
}
  • 我们使用realloc函数动态开辟空间进行扩容,而扩容的大小则为原来容量的2倍 (这样比较合理,扩容多了浪费空间,扩容少了空间又不够)

3.5 尾插

void SLPushBack(SL* psl, SLDataType x)
{assert(psl);CheckCapacity(psl);psl->a[psl->size++] = x;
}
  • 对于psl指针,如果有人误传了NULL,则会导致程序崩溃,所以最好在每个函数前断言assert,保证psl指针的有效性
  • 先检测是否需要扩容
  • 再根据当前已有的元素个数,对数组进行下标访问并赋值,size++

3.6 头插

void SLPushFront(SL* psl, SLDataType x)
{assert(psl);CheckCapacity(psl);int end = psl->size - 1;while (end >= 0){psl->a[end + 1] = psl->a[end];end--;}psl->a[0] = x;psl->size++;
}
  • 先检测是否需要扩容
  • 再用循环将数组中每个元素向后挪动一格,最后在头部插入数据,size++

3.7 尾删

void SLPopBack(SL* psl)
{assert(psl);assert(psl->size > 0);psl->size--;
}
  • 使用断言assert,保证size大于零,不会造成越界访问
  • 直接让size- -,使得不再能够访问尾部数据

3.8 头删

void SLPopFront(SL* psl)
{assert(psl);assert(psl->size > 0);int start = 0;while (start < psl->size - 1){psl->a[start] = psl->a[start + 1];start++;}psl->size--;
}
  • 用循环将数组中每个元素向前挪动一格,覆盖头部数据,实现头部删除,size- -

3.9 指定插入

void SLInsert(SL* psl, int pos, SLDataType x)
{assert(psl);assert(pos >= 0 && pos <= psl->size);CheckCapacity(psl);int end = psl->size - 1;while (end >= pos){psl->a[end + 1] = psl->a[end];end--;}psl->a[pos] = x;psl->size++;
}
  • 断言assert保证pos不会越界
  • 输入指定位置的下标,用循环将pos往后的所有数据向后挪动一格 ,再于指定位置插入数据,size++

我们可以运用这个应用更广的指定插入,来实现头插和尾插 ,以此增强函数的复用性

尾插

void SLPushBack(SL* psl, SLDataType x)
{assert(psl);SLInsert(psl, psl->size, x);
}

头插

void SLPushFront(SL* psl, SLDataType x)
{assert(psl);SLInsert(psl, 0, x);
}

3.10 指定删除

void SLErase(SL* psl, int pos)
{assert(psl);assert(pos >= 0 && pos < psl->size);int start = pos + 1;while (start < psl->size){psl->a[start - 1] = psl->a[start];start++;}psl->size--;
}
  • 断言assert保证pos不会越界(此处与指定插入比少了一个等号,仔细思考一下为什么?)
  • 输入指定位置的下标,用循环将pos往后的所有数据向前挪动一格 ,以此覆盖pos位置的数据,达到指定删除的目的

我们可以运用这个应用更广的指定删除,来实现头删和尾删 ,以此增强函数的复用性

尾删

void SLPopBack(SL* psl)
{assert(psl);SLErase(psl, psl->size - 1);
}

头删

void SLPopFront(SL* psl)
{assert(psl);SLErase(psl, 0);
}

3.11 查找

int SLFind(SL* psl, SLDataType x)
{assert(psl);int i = 0;for (i = 0; i < psl->size; i++){if (psl->a[i] == x){return i;}}return -1;
}
  • for循环遍历数组,找到返回下标,找不到返回-1

3.12 修改

void SLModify(SL* psl, int pos, SLDataType x)
{assert(psl);assert(pos >= 0 && pos < psl->size);psl->a[pos] = x;
}
  • 直接通过下标访问数组进行修改

3.13 打印

void SLPrint(SL* psl)
{assert(psl);int i = 0;for (i = 0; i < psl->size; i++){printf("%d ", psl->a[i]);}
}

真诚点赞,手有余香

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

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

相关文章

error while loading shared libraries 找不到动态库问题如何解决

在使用 c 或 c 开发应用时&#xff0c;在启动程序时&#xff0c;有时会遇到这个错误&#xff0c;找不到动态库。这个时候&#xff0c;我们使用 ldd 来查看&#xff0c;发现可执行文件依赖的动态库显示为 not found。 1 实验代码 使用如下 3 个文件做实验。 hello.h 中声明了函…

【Vue】修改数量

文章目录 底部总价展示完整代码 注意&#xff1a;前端 vuex 数据&#xff0c;后端数据库数据都要 注册点击事件 页面中dispatch action 提供action函数 提供mutation处理函数 底部总价展示 提供getters 动态渲染 完整代码 main.js import Vue from vue import App from…

Linux:基础开发工具

文章目录 Linux 软件包管理器 yum什么是软件包关于rzsz查看软件包安装软件卸载软件安装扩展源 Linux 编辑器 vimvim的基本概念正常/普通/命令模式(Normal mode)插入模式(Insert mode)底行模式(last line mode) vim的基本操作[命令模式]切换至[插入模式][插入模式]切换至[命令模…

【CW32F030CxTx StartKit开发板】开发资料

本来是参加21ic的评测活动&#xff0c;不知道为什么评测文章一直被提示有不良内容&#xff0c;所以只好先在此记录一下相关的资料。 此次测试的是CW32F030CxTxStartKit 评估板。该开发板为用户提供一种经济且灵活的方式使用 CW32F030CxTx 芯片构建系统原型&#xff0c;可进行性…

激活乡村振兴新动能:推动农村产业融合发展,打造具有地方特色的美丽乡村,实现乡村全面振兴

目录 一、推动农村产业融合发展 1、农业产业链条的延伸 2、农业与旅游业的结合 二、挖掘地方特色&#xff0c;打造美丽乡村 1、保护和传承乡村文化 2、发展特色农业 三、加强基础设施建设&#xff0c;提升乡村品质 1、改善农村交通条件 2、提升农村水利设施 四、促进…

吴恩达2022机器学习专项课程C2W2:2.23 选修_反向传播算法的工作原理(什么是导数图计算大型神经网络)

目录 引言一.导数的计算1.epsilon与导数的关系2.其它导数符号形式3.导数小结 二.小型神经网络的计算图1.什么是计算图&#xff08;前向传播过程&#xff09;2.反向传播计算过程3.验证反向传播的计算结果4.为什么用反向传播计算导数&#xff1f; 三.扩大神经网络的计算图1.计算反…

笔记本充电出现了问题。

不知道为什么。电池充电图片一直显示的空。谁能救救我&#xff01;

C51学习归纳9 --- I2C通讯学习(重点)

首先&#xff0c;我自己学习过以后的直观感觉&#xff0c;通信协议是单片机的灵魂之一&#xff0c;只有规定好了通信协议我们才能够正确的接收到信息&#xff0c;才能实现更加深入的研究。所以这一部分是需要好好学习的。 本节借助一个可存储的芯片AT24C02&#xff0c;进行在I2…

C语言怎样初始化图形模式?

一、问题 在C语⾔中&#xff0c;initgraph( ) 函数⽤于初始化图形模式。初始化时&#xff0c;那么多参数都是⼲什么的&#xff1f;怎样设置&#xff1f; 二、解答 initgraph( ) 函数⽤于初始化图形模式&#xff0c;其语法格式如下。 void far initgraph(int far * gdriver, i…

对象存储OSS 客户端签名直传的安全风险和解决方法

1. 前言 阿里云对象存储OSS&#xff08;Object Storage Service&#xff09;是一款海量、安全、低成本、高可靠的云存储服务&#xff0c;可提供99.9999999999%&#xff08;12个9&#xff09;的数据持久性&#xff0c;99.995%的数据可用性。多种存储类型供选择&#xff0c;全面…

11.链表

数组的分类&#xff1a;便于遍历 静态数组&#xff1a;int arr[10]数据过多造成空间溢出&#xff0c;数据过小空间浪费 动态数组&#xff1a;malloc calloc realloc 合理利用空间不能快捷的插入或删除数据&#xff08;会涉及到大量的数据移动&#xff09; 知识点一&#xff1…

玉米粒计数检测数据集VOC+YOLO格式107张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;107 标注数量(xml文件个数)&#xff1a;107 标注数量(txt文件个数)&#xff1a;107 标注类别…

二分#背包#快排#LCS详解

二分#背包#快排#LCS详解 文章目录 二分#背包#快排#LCS详解1. 二分搜索2. 01背包问题3. 快速排序4. 最长公共子序列 1. 二分搜索 在处理大规模数据集时&#xff0c;查找操作的效率显得尤为重要。二分搜索是一种在有序数组中查找目标值的高效算法&#xff0c;其时间复杂度为O(lo…

【python报错】关于 xlrd.biffh.XLRDError: Excel xlsx file; not supported 解决方法【已解决】

【Python报错】关于xlrd.biffh.XLRDError: Excel xlsx file; not supported解决方法【已解决】 在使用Python进行数据分析时&#xff0c;经常需要处理Excel文件。xlrd库是一个流行的用于读取Excel文件的库&#xff0c;但如果你在使用xlrd打开.xlsx文件时遇到了xlrd.biffh.XLRDE…

区块链(Blockchain)调查研究(一)

文章目录 1. 区块链是什么&#xff1f;2. 区块链分类和特点3. 区块链核心关键技术3.1 共识机制3.2 密码学技术3.4 分布式存储3.5 智能合约 4. 区块链未来发展趋势5. 区块链能做什么、不能做什么&#xff1f;5.1 第一部分5.2 第二部分5.3 第三部分&#xff08;结论&#xff09; …

新书推荐:2.3 消息机制

Windows程序的消息机制是指在Windows操作系统下&#xff0c;应用程序与操作系统之间的一种通信方式。通过消息机制&#xff0c;应用程序可以接收来自操作系统的各种事件和请求&#xff0c;以便做出相应的响应和处理。 在Windows程序中&#xff0c;消息机制的实现是基于消息队列…

用 Axios 封装一个双 token 无感刷新

为什么要用双Token无感刷新&#xff0c;它解决了什么问题&#xff1f; 为了保证安全性&#xff0c;后端设置的Token不可能长期有效&#xff0c;过了一段时间Token就会失效。而发送网络请求的过程又是需要携带Token的&#xff0c;一旦Token失效&#xff0c;用户就要重新登陆&…

欢乐打地鼠小游戏html源码

这是一款简单的js欢乐打地鼠游戏&#xff0c;挺好玩的&#xff0c;老鼠出来用鼠标点击锤它&#xff0c;击中老鼠获得一积分。 欢乐打地鼠小游戏html源码

kopf,一个实用的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个实用的 Python 库 - kopf。 Github地址&#xff1a;https://github.com/nolar/kopf 在 Kubernetes 中&#xff0c;Operator 是一种用于扩展 Kubernetes 功能的强大工具。Operator 可以自动化应…

MySQL的group by与count(), *字段使用问题

文章目录 问题group by到底做了什么举个例子简单来说为什么select字段&#xff0c;count()不能和*共同使用总结 问题 这是一段摘抄自MySQL官网的文字。其大致意思是MySQL拓展了group by的使用&#xff0c;MySQL允许选择没有出现在group by中的字段。换句话说&#xff0c;标准SQ…