数据结构之线性表(顺序表的实现)

目录

一、线性表的原理

二、线性表的实现(顺序表)

1.定义顺序表

2.初始化顺序表

3.判断顺序表是否为空

4.获取顺序表的长度

5.向顺序表中插入元素

6.删除指定位置的元素

7.遍历顺序表

8.得到指定位置的元素

三、打印测试功能

1.测试

2.结果输出

3.总代码 

四、顺序表的优缺点

1.顺序表的优点:

2.顺序表的缺点


一、线性表的原理

       线性表,从名字上你就能感觉到,是具有像线一样的性质的表。在广场上,有很多人分散在各处,当中有些是小朋友,可也有很多大人,甚至还有不少宠物,这些小朋友的数据对于整个广场人群来说,不能算是线性表的结构。

        但像刚才提到的那样,一个班级的小朋友,一个跟着一个排着队,有一个打头,有一个收尾,当中的小朋友每一个都知道他前面一个是谁,他后面一个是谁,这样如同有一根线把他们串联起来了。就可以称之为线性表。

线性表(List) : 零个多个数据元素的有限序列。

二、线性表的实现(顺序表)

1.定义顺序表

         主要完成一些常量的定义以及创建线性表的操作。

#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;typedef struct
{ElemType data[MAX_SIZE];int length;
}SqList;
2.初始化顺序表

         初始化主要指对表的数量置为0。

// 初始化顺序表
Status InitList(SqList* L)
{if (L == NULL){return ERROR;}L->length = 0;return OK;
}
// 重置顺序表
Status ClearList(SqList* L)
{if (L == NULL){return ERROR;}L->length = 0;return OK;
}
3.判断顺序表是否为空

        对表中的length长度进行判断。

// 判断是否为空
Status isEmpty(SqList* L)
{if (L->length > 0){return FALSE;}else if(L->length == 0 || L->length == NULL){return TRUE;}
}
4.获取顺序表的长度

       getter操作,返回length长度。

// 获取长度
int ListLength(SqList* L)
{return L->length;
}
5.向顺序表中插入元素

        主要用到for循环操作,让后一位的值等于前一位的值,其中 index 指的是第几个元素

需要注意:要用的for循环的逆向循环,因为正向循环最后一位元素无法向后进一。

如图所示: 

        代码主要为: 

// 插入元素
Status InsertList(SqList* L, int index, const ElemType e)
{if ( (index >= 1) && (L->length < MAX_SIZE)){if ((index <= L->length)){for (int k = L->length - 1; k >= index - 1; k-- ){L->data[k + 1] = L->data[k];}}L->data[index - 1] = e;L->length++;return OK;}return ERROR;
}
6.删除指定位置的元素

         原理和插入元素一样,都是用到for循环,对数据进行赋值操作。同样这里需要用的for循环的正向遍历。

        如图所示:

        代码为:

// 删除元素
Status DeleteList(SqList* L, int index, ElemType* e)
{ if (L->length == 0 || index < 1 || index > L->length) return ERROR;if (index < L->length){*e = L->data[index - 1];for (int k = index - 1; k < L->length; k++){L->data[k] = L->data[k + 1];}L->length--;return OK;}
}
7.遍历顺序表

        很简单,就是简单的数组遍历。

Status visit(ElemType e)
{printf("%d->", e);return OK;
}
// 遍历
Status ListTraverse(SqList* L)
{for (int i = 0; i < L->length; i++){visit(L->data[i]);}printf("\n");return OK;
}
8.得到指定位置的元素

        根据索引位置,获取指定元素的值。

Status GetElem(SqList* L, int index, ElemType* e)
{if (L->length == 0 || index < 1 || index > L->length) return ERROR;*e = L->data[index - 1];return OK;
}

三、打印测试功能

1.测试

        输入以下代码,测试功能:

int Createlist()
{SqList L;ElemType e;Status ret;ret = InitList(&L);for (int i = 0; i < 5; i++){ret = InsertList(&L, 1, i);}ListTraverse(&L);ret = isEmpty(&L);printf("L是否为空, %d(1: 空; 0: 否)\n",ret);DeleteList(&L, 2, &e);printf("删除的第二个元素为:%d\n", e);ListTraverse(&L);GetElem(&L, 3, &e);printf("得到第三个的元素为:%d\n", e);for (int i = 5; i < 10; i++){ret = InsertList(&L, 2, i);}ListTraverse(&L);// 清空ClearList(&L);return 0;
}
2.结果输出

        如图所示:

3.总代码 

        代码如下:

#include <iostream>#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;typedef struct
{ElemType data[MAX_SIZE];int length;
}SqList;// 初始化顺序表
Status InitList(SqList* L)
{if (L == NULL){return ERROR;}L->length = 0;return OK;
}
// 重置顺序表
Status ClearList(SqList* L)
{if (L == NULL){return ERROR;}L->length = 0;return OK;
}// 判断是否为空
Status isEmpty(SqList* L)
{if (L->length > 0){return FALSE;}else if(L->length == 0 || L->length == NULL){return TRUE;}
}// 获取长度
int ListLength(SqList* L)
{return L->length;
}// 插入元素
Status InsertList(SqList* L, int index, const ElemType e)
{if ( (index >= 1) && (L->length < MAX_SIZE)){if ((index <= L->length)){for (int k = L->length - 1; k >= index - 1; k-- ){L->data[k + 1] = L->data[k];}}L->data[index - 1] = e;L->length++;return OK;}return ERROR;
}// 删除元素
Status DeleteList(SqList* L, int index, ElemType* e)
{ if (L->length == 0 || index < 1 || index > L->length) return ERROR;if (index < L->length){*e = L->data[index - 1];for (int k = index - 1; k < L->length; k++){L->data[k] = L->data[k + 1];}L->length--;return OK;}
}Status visit(ElemType e)
{printf("%d->", e);return OK;
}
// 遍历
Status ListTraverse(SqList* L)
{for (int i = 0; i < L->length; i++){visit(L->data[i]);}printf("\n");return OK;
}Status GetElem(SqList* L, int index, ElemType* e)
{if (L->length == 0 || index < 1 || index > L->length) return ERROR;*e = L->data[index - 1];return OK;
}int Createlist()
{SqList L;ElemType e;Status ret;ret = InitList(&L);for (int i = 0; i < 5; i++){ret = InsertList(&L, 1, i);}ListTraverse(&L);ret = isEmpty(&L);printf("L是否为空, %d(1: 空; 0: 否)\n",ret);DeleteList(&L, 2, &e);printf("删除的第二个元素为:%d\n", e);ListTraverse(&L);GetElem(&L, 3, &e);printf("得到第三个的元素为:%d\n", e);// 继续添加元素for (int i = 5; i < 10; i++){ret = InsertList(&L, 2, i);}ListTraverse(&L);// 清空ClearList(&L);return 0;
}int main()
{return Createlist();
}

四、顺序表的优缺点

1.顺序表的优点:

(1)无须为表示表中元素之间的逻辑关系而增加额外的存储空间

        这是个什么意思呢?就是这为什么是一个优点啊?我们实际上顺序表当中这个元素,它们之间的这个逻辑关系呢,是一个单纯的就是个什么线性关系,就是一个挨着一个一个挨着一个。所以你不用去额外的有一个东西去记录它们之间的这样一个关系。

        很快,我们就会学习到链表。那么,在链表当中呢?我们就额外用了一些东西去记录前一个元素和后一个元素之间的一个关系。所以那个地方是要消耗额外的存储空间的啊,这个但是在顺序表当中呢,它是不需要的。这是它的一个优点,这就意味着你记下来的数据全都是有效数据。基本上没有什么这个冗余数据,但是像比如说我们后面学到链表或者是以后我们学到其他数据结构,它多多少少还是一些冗余数据,有一些东西它是用来表达或者是记录元素和元素之间关系的,但顺序表是不需要的 。

(2)可以快速地读取表中任一位置的元素 

         这一点也是其他结构,或者说其他数据结构很难做到的一个事情。不要看这个东西很简单。呃,但是它其实是很难做到,就是你在用这样的一些数据结构的时候,你一定要搞清楚你的主要诉求是什么?如果这个写入或者是新增这样的操作,在你的这个里面占比并不是很大的情况下。那么,你读取将是一个很重要的一个性能指标。

2.顺序表的缺点

(1)插入和删除操作需要移动大量元素

        那它缺点肯定也是一样,那首先第一个就是你插入和删除的话,需要移动大量元素。为什么?因为你元素之间没有逻辑关系的额外存储空间呐。我删掉了一个,比如说这样的一个线性表是吧?我把中间这块删掉了,你就得把后面的往前挪。你不挪的话,那这中间就空了一个元素出来,这个元素不在这个里面,它是个空的空的,那这样子行不行?不行为什么?因为我没有额外的东西记录啊,我这后面一个可以跳一个没有这样的存储空间给它,所以这个东西它是它的优点。到了这里,就是它的缺点。

        你就必须要移动,你在中间删了一个就要移动,你移你要删除了这个头部的,你得把所有的都往前面移动一次。所以它最坏的情况下呢,你要移动n次也就这个移动的这个玩意儿,它是一个O(n)的时间复杂度,随着你的规模是线性增增加的。啊,移动最坏情况下是O(n)那么最差的情况下呢?那你也是要平均水平也是一半吧?对吧,随机出现的话,平均水平也是要一半吧,当然如果是删除尾巴上的是最轻松的,直接把它删掉就完就完事儿了,把长度缩减一就OK了。

(2)当线性表长度变化较大时,难以确定存储空间的容量 

        当这个线性表长度变化较大的时候,很难确定存储空间的容量,因为你看我们的这个线性表顺序表它是一开始我们就给了20最大的空间。然后呢?根据这个长度呢去?实际使用的这个长度会根据呃,这个东西去变化啊,它的这个长度变量length变量会根据实际使用的长度去变化。那么你在这个20范围以内。当然是OK的,没问题,这个效率都很高,不管你是增加还是减少,都还比较高,但是一旦这个变化很大。

        如果比如说你从20变成200的时候,这个时候就不好说了,当然现在的计算机来讲的话,你额外增加的180个元素,它也许是有内存空间的。但是如果你存的每一个结构,每一个这个单元,它的数据本身就很大的情况下,你再增加180个。这个东西你能增加的上去吗?不好说对不对,然后你如果这个使用的长度又突然一下缩减,就是一下子增的很长。一下子呢,又减的很厉害,这种情况有没有有什么样的情况?

        就是比如说像这个数据包的这样一个队列。啊,数据包的一个队列,我们要去做一个数据包啊,我从客户端收到数据包,那高峰时期它就是很长啊。它可能一瞬间能达到1000多。1000多个包,瞬间发过来很正常啊,然后但是有时候出现问题,可能到了晚上三四点钟可能一个,两个包发过来,甚至一个包都没有啊。那这个存储空间弹性就非常变化,非常大,这个东西就比较麻烦,如果你申请多了吧,浪费存储空间,因为这个东西你申请了占着没用它。 

(3)造成存储空间的"碎片" 

        这个就是我们实际上就是遇到过这样的一些情况,我们这个里面是20,但是我们用到用满了20吗?在我们的测试当中,一直没有对不对?我们最多的时候用到了10。剩下的这些东西都是都是空的啊,那么当我在这里面删除一个以后,我要把所有东西都往前面移,都往前面移,那么在这个移动过程中,最后又会空出来一个这个东西,一直在这里。如果你有大量的这种队列是吧?你有一个两个三个这样的队列,每个队列多多少少是吧?就有一点空的。那这些东西是不是没有用的?这些东西算是一个碎片呢。

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

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

相关文章

全球相机控制面板市场展望与未来增长机遇:预计未来六年年复合增长率CAGR为4.3%

在全球摄影器材和专业影像设备需求增长的背景下&#xff0c;相机控制面板正成为市场的焦点。本文详细分析了全球相机控制面板市场的现状、增长趋势及未来前景&#xff0c;旨在为投资者和业内人士提供深入的市场洞察和指导。 市场概览 据恒州诚思团队研究分析显示&#xff0c;2…

RK3568笔记四十七:PWM 子系统

若该文为原创文章&#xff0c;转载请注明原文出处。 pwm 子系统功能单一&#xff0c;很少单独使用&#xff0c;一般用于控制显示屏的背光、控制无源蜂鸣器、伺服电机、电压调节等等。 一、PWM介绍 PWM(Pulse width modulation)&#xff0c;脉冲宽度调制。在内核中 PWM 驱动较简…

学习大数据DAY26 简单数据清洗练习和 Shell 脚本中的数据库编程

目录 上机练习 14 mysql 命令 sql 语句实现步骤 shell 脚本导入 csv 格式文件到 mysql 数据库 secure-file-priv 特性 把文件拷贝到 mysql 指定目录下 上机练习 15 mysqldump 命令 上机练习 16 上机练习 14 运用上一节课学的 Shell 工具完成 1. 清洗数据《infotest.t…

CentOS7 yum报错Cannot find a valid baseurl for repo

问题 Loaded plugins: fastestmirror Determining fastest mirrors Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx86_64&repoos&infravag error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown…

前端canvas——五子棋小游戏开发

这估计是最后一篇了&#xff0c;终于是修复了部分bug——隔一个空格能够胜利的bug&#xff0c;并且添加了部分样式。 其他bug目前还没有找到&#xff0c;找到再说吧。 大部分代码请见&#xff1a; 用canvas实现五子棋小游戏https://blog.csdn.net/m0_54066656/article/detail…

后端笔记(2)--JDBC

1.JDBC简介 *JDBC(Java DataBase Connectivity)就是使用java语言操作关系型数据库的一套API *JDBC本质&#xff1a;&#xff08;可以使用同一套代码&#xff0c;操作不同的关系型数据库&#xff09; ​ *官方定义的一套操作所有关系型数据库的规则&#xff0c;即接口 ​ *各…

ESP之经典蓝牙库BluetoothSerial介绍和实例演示

ESP之经典蓝牙库BluetoothSerial介绍和实例演示 1.概述 目前ESP32内置了双模蓝牙&#xff08;蓝牙4.0版本之前都是经典蓝牙&#xff0c;4.0版本成为BLT低功耗蓝牙转为物联网开发。双模指的就是这款芯片两种模式都支持&#xff09;。 这篇文章介绍ESP32蓝牙的经典模式使用方法…

算法学习day23

一、k个一组翻转链表 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 思路&#xff1a; 1.首先得到链表的长度size&#xff1b;然后在size>k的范围里面进行翻转长度为k的链表。 2.while(size>k) 在这个循环中&#xf…

【C++BFS算法】886. 可能的二分法

本文涉及的点 CBFS算法 LeetCod886. 可能的二分法 给定一组 n 人&#xff08;编号为 1, 2, …, n&#xff09;&#xff0c; 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人&#xff0c;那么他们不应该属于同一组。 给定整数 n 和数组 dislikes &#xff0c;其…

电脑桌面记事本便签哪个好,有哪些好用的桌面备忘记事工具推荐

在寻找高效办公的道路上&#xff0c;我们经常需要记住许多重要的事情&#xff0c;然而人的记忆力终究有限&#xff0c;这时候就需要依赖一些工具来帮助我们进行提醒。一款好的电脑桌面记事本便签、桌面日程安排软件就像是一位得力助手&#xff0c;它不仅能够帮助我们合理规划时…

项目经理的开源工具指南:优化您的选择过程

国内外主流的10款开源项目管理系统对比&#xff1a;PingCode、Worktile、禅道、Teambition、Gogs、码云 Gitee、Jira、Redmine、ProjectLibre、OpenProject。 在选择合适的开源项目管理系统时&#xff0c;很多团队面临诸多挑战&#xff1a;功能是否全面&#xff1f;易用性如何&…

Excel模拟计算演示-以矩阵乘计算密度为例

Excel模拟计算演示-以矩阵乘计算密度为例 1.参考链接2.CUDA_Occupancy_Calculator截图3.矩阵乘计算密度模拟计算的操作步骤及效果 安装好CUDA之后,/usr/local/cuda-12.1/tools/CUDA_Occupancy_Calculator.xls里会看到"TABLE(,B17)"这样的表达式,原来是模拟计算的结果…

3V升5V输出800mA可驱动10MA驱动蜂鸣片芯片AH6910

135-3806-7573今天&#xff0c;我们将深入解析一款名为AH6910的芯片&#xff0c;这款芯片以其独特的3V至5V宽电压输入范围、800mA的高输出电流能力&#xff0c;以及能够轻松驱动低至10mA需求的蜂鸣片&#xff0c;成为了众多电子项目中的优选元件。######一、AH6910芯片概述 AH…

RIP路由协议

RIP-路由信息协议V1/V2/NG NG版为ipv6专用 距离矢量型IGP路由协议&#xff0c;使用跳数作为度量&#xff0c;支持等开销负载均衡&#xff1b;基于UDP&#xff0c;520端工作&#xff0c;基于UDP V1和V2的区别&#xff1a; 1、v1为有类别协议--不支持VLSM/CIDR&#xff0c;即使使…

ic进阶|性能篇02:一文带你了解一种特殊的并行技术-展开!

本期文章让我们聊聊一种数字ic设计技术——展开&#xff0c;展开用于产生一个一次迭代就相当于原有结构的多次迭代的新电路结构。其相当于之前聊过的折叠技术的反向操作&#xff0c;折叠使用一个功能单元通过多次迭代来完成原有电路结构一次迭代的操作&#xff0c;相对于通过时…

中电金信:云原生时代IT基础设施管理利器——基础设施即代码(IaC)

在数字化转型、零售业务快速发展、信创建设驱动下&#xff0c;应用架构、技术架构、基础架构都已向云原生快速演进&#xff0c;银行业IT基础设施管理产生了非常大的变化&#xff0c;当前银行业&#xff0c;正在开展新一轮的核心应用系统重构、基础平台统一建设等重点任务&#…

Playwright 的使用

Playwright 的特点 支持当前所有主流浏览器&#xff0c;包括 Chrome 和 Edge &#xff08;基于 Chromiuns&#xff09;, Firefox , Safari 支持移动端页面测试&#xff0c;使用设备模拟技术&#xff0c;可以让我们在移动Web 浏览器中测试响应式的 Web 应用程序 支持所有浏览…

x264编解码库 -介绍和使用示例

目录 1&#xff1a;X264简单介绍 1.1&#xff1a;编译x264 1.2&#xff1a;x264简单介绍 1.3&#xff1a;x264的优势 1.4&#xff1a;x264与FFmpeg的关系 1.5&#xff1a;x264 编解码原理 1.6 进一步学习资源 2&#xff1a;demo效果 3&#xff1a;完整代码 4&#xff1a;附件…

6 网络

6 网络 1、概念2 IP地址3、套接字4、TCP协议4.1 TCP协议的基本特征4.2 建立连接4.4 终止连接4.5 编程模型 5、UDP协议5.1 UDP协议的基本特性5.2 常用函数5.3 UDP通信模型 6、域名解析 1、概念 计算机网络是实现资源共享和信息传递的计算机系统 ISO/OSI网络协议模型 TCP/IP协…

C语言进阶 10. 字符串

C语言进阶 10. 字符串 文章目录 C语言进阶 10. 字符串10.1. 字符串10.2. 字符串变量10.3. 字符串输入输出10.4. 字符串数组10.5. 单字符输入输出10.6. 字符串函数strlen()10.7. 字符串函数strc()10.8. 字符串函数strcpy()10.9. 字符串搜索函数10.10. PAT10-0. 说反话 (20)10-1.…