顺序表的简单介绍

目录

前提须知:

数据结构:

什么是数据结构?

数据结构特点:

 为什么需要数据结构:

顺序表:

线性表:

与数组区别:

静态顺序表与动态顺序表:

二者之间的区别:

编译器的实现:(以下使用头文件和源文件的书写方式)

初始化:

头文件:

源文件:

 销毁开辟空间:

头文件:

源文件: 

尾插:(在上述代码的基础上进行尾插操作)

尾插要考虑的因素:

头文件:

回答问题:

 1)空间是否足够:

2)空间足够如何进行尾插:

如何扩容?

怎么扩容?

那如何申请空间呢?

注意事项:

头插:(在上诉代码的基础上进行尾插操作)

 头插的所需要进行思考的问题:

头文件: 

回答问题:

 怎么将原先的数据往后移,腾出第一个空间的位置:

尾删:(在上诉的基础上进行尾删操作)

头文件:

需要注意的问题:

头删:(在上诉代码的基础上进行头删)

 头文件:


前提须知:

数据结构:

什么是数据结构?

答:数据结构是计算机存储、组织数据的⽅式,举例:数组是最简单的一种数据结构。

数据结构特点:
  •  能够存储数据(如顺序表、链表等结构)
  • 存储的数据能够⽅便查找 
 为什么需要数据结构:
  • 最基础的数据结构能够提供的操作已经不能完全满⾜复杂算法实现。
  • 假设数据量⾮常庞⼤,频繁的获取数组有效数据个数会影响程序执⾏效率。
  • 数据的多样性,以数组为例,数组只能满足同一种类型的数据,不能满足其他类型的数据。

顺序表:

 在顺序表之前,我们要先明白什么是线性表。

线性表:

  • 线性表是一种总称, 指的是具有相同特性的一类数据结构的统称。

线性表特点:

  • 线性表在逻辑上是线性结构,也就说是连续的一条直线。
  • 但是在物理结构上并不一定是连续的线性表在物理上存储时,通常以数组和链式结构的形式存储。
  • 逻辑结构:人为想象的。
  • 物理结构:内存存储上,不一定是连续的,连续的举例是数组,数组地址是连续的。

而顺序表是线性表的一种,相当于苹果是水果的一种,且因为顺序表的底层结构是数组,所以顺序表在逻辑结构上是线性的,在物理结构上也是线性的。

与数组区别:

 先前讲诉过,数组是同种类型数据的集合。

而且数组分为两种,定长数组和动态数组,定长数组是一开始就设定了数组大小,动态数组是数组的大小不确定,详情看柔性数组。

柔性数组_明 日 香的博客-CSDN博客

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

同时也可以通过数组的分类将顺序表分为两种,静态顺序表和动态顺序表。

静态顺序表与动态顺序表:

静态顺序表和动态顺序表的声明结构,其实顺序表的声明结构就是一种结构体。

结构体的简单介绍(1)_明 日 香的博客-CSDN博客

//静态顺序表struct SeqList
{int a[100];//定长数组int size; //有效个数}
  •  int a[100]表示这个顺序表的大小是100个int类型的字节数大小,也可以说是400个字节大小。
  • 而int size 表明了该顺序表中放入了多少有效的数据。
  • struct是结构体的关键字,表明了顺序表的声明结构其实就是结构体。
//动态顺序表struct SeqList
{int* a;int size;//有效数据的个数int capacity;//空间大小
}
  • int*a 指向的是一个数组空间的首个元素地址,间接表明了顺序表的底层结构是数组。
  • int capacity 指向的是开辟空间的大小,也就是顺序表空间的大小,因为是动态的,所以需要开辟空间。
  • 在使用的过程中,可以将a直接当成数组名使用,这是允许的。

二者之间的区别:

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

编译器的实现:(以下使用头文件和源文件的书写方式)

注意:顺序表是一种声明,所以应该在头文件中输写。 

 

以动态顺序表为例子。

在图中,typedef 将int 类型 和 顺序表 进行了重新命名。

int 类型 定义命名的意义是为了方便以后进行类型的更改,这是顺序表和数组的区别之一。

而顺序表 struct SeqList重命名为SL 为了以后方便书写。


 

初始化:

创建一个void 类型的函数SLInit 该函数的参数是SL*类型的,形参是ps

头文件:

 

源文件:

结构体的赋值,详情:结构体的简单介绍(1)_明 日 香的博客-CSDN博客 

将顺序表的空间大小和有效数字初始化为0,将顺序表的指针指向NULL 

因为局部变量的关系,以及传值调用中,形参的改变不会影响实参的因素,所以我们这里使用传址调用。

C语言 实参与形参 传值调用与传址调用-CSDN博客


 

 销毁开辟空间:

销毁开辟的空间,在销毁之前我们必须判断这个空间是否存在,或者说是否开辟,如果存在,则需要使用free释放空间,free的本质是将开辟的空间交还给内存。

free详情:malloc与free_明 日 香的博客-CSDN博客

头文件:

源文件: 


 

尾插:(在上述代码的基础上进行尾插操作)

在尾部插入数据。

如图所示,在下标为6的位置上插入数据,这种就是尾插。

尾插要考虑的因素:
  1. 空间是否足够的问题?
  2. 足够应该如何进行尾插?
  3. 如若空间不够应该如何扩容的问题?
  4. 扩容时需要注意什么?
  5. 需要扩容多少空间合适?
头文件:

回答问题:
 1)空间是否足够:

在动态顺序表中,capacity是表示顺序表的空间的大小,size是表示顺序表中的有效数据的个数,所以当capacity==size的时候,就可以说明顺序表的空间是否满了。

  • 顺带一提,capacity表示的是空间大小,而size表示的是有效数据的个数,所以当二者相同时,二者均可以代表顺序表这个数组的数组大小,而不相同时,反倒是size可以代表顺序表这个数组的数组大小,而顺序表这个数组的最大下标则就是size-1 

使用if进行判断二者是否相等,如若相等,准备进行空间的扩容,若不相等则直接进行尾插。 

2)空间足够如何进行尾插:

 因为空间足够使用,所以在顺序表这个数组中插入数据即可。

且,因为size无论在何时都表明了数组的大小,而size-1表明了当前顺序表这个数组的最大下标,所以在顺序表这个数组中,若要插入数据,直接在size这个位置中插入数据即可。 

当然,在最后别忘了将 有效数据个数+1,这是为了进行多次的尾插所必要的代码,且直接插入是基于capacity 够的情况下,所以capacity不需要进行改动。

如何扩容?怎么扩容?需要扩大多少空间合适?

如何扩容?
  • 使用realloc函数进行扩容,realloc函数详情:realloc-CSDN博客 
怎么扩容?
  • 每次插入一个数据就申请一个空间?插入100个数据申请一百个空间?
  • 但是如果频繁的扩容,会降低程序的性能。
那如何申请空间呢?
  • 答:一般以2倍或者1.5倍进行扩容,比如一开始申请4个空间,当插入第五个数据的时候,扩容成八个空间,插入第九个数据的时候,扩容成16个空间,以此类推··················

图中的代码类比,realloc函数的调整空间大小,基于realloc函数的特性,如若调整空间大小失败,那么这个空间则会丢失,所以直接赋予ps->a有可能造成原空间地址失效,所以需要使用tmp进行中间赋值,然后判断,判断成功后在赋予ps->a


扩容:

  • ps->a表示需要扩容空间的起始地址
  • ps->capacity*2*sizeof(SLDataType),前者表示当前的空间大小,sizeof表示计算当前顺序表的字节大小,*2表示我们的扩容方法。
  • (需要注意的是,空间大小是有类型的,所以空间大小不能代表字节数的多少) 

注意:

当扩容成功后,记得地址的转移以及当前空间需要扩大到原来的两倍,以便下次扩容的时候不会出错。 

注意事项:

 有些人会将capacity 初始化为0,导致后面的代码出错,所以这里新建立一个代码进行判断。

 

 这是一个三目表达式,使用该表达式进行判断空间大小是否为0,如果是0则赋予初值4,如果不是0则将空间进行扩容。

也因此,其余部分也需要进行整改。

完整的代码是:当空间不够后进行扩容,扩容后空间足够,进行尾插操作 


 

头插:(在上诉代码的基础上进行尾插操作)

头插,在头部插入数据,但是放在数组中,就相当于将原先的首元素变为第二个元素,原先的第二个元素变成第三个元素······在不覆盖其他元素的基础上腾出第一个空间的位置。

 头插的所需要进行思考的问题:
  1. 空间不够(已解决)
  2. 怎么将原先的数据往后移,腾出第一个空间的位置。
头文件: 

回答问题:
 怎么将原先的数据往后移,腾出第一个空间的位置:

  • 因为size-1对应的是顺序表这个数组的最大下标,所以将这个最大下标所对应的数据往后移一个位置,也就是size表示的这个数字下,并且进行持续性的进行下标-1的循环,进行不断的挪到。
  • 挪动到最后下标为0后停止,并且对下标为0的位置空间进行数据的插入。
  • 最后别忘记有效数字的+1

 

尾删:(在上诉的基础上进行尾删操作)

头文件:

 因为尾删不用管空间是否足够,所以我们需要删除最后一个数据就行了。

也因为不用管空间大小,所以直接进行有效数据的个数-1使得最后尾部的数据失效即可。

需要注意的问题:

 注意在尾删的同时要注意顺序表是否为空,我们需要进行判断,判断是否为空要判断p->size==0是否成立,成立就为空的。

在这里我们使用断言进行判断预警 


头删:(在上诉代码的基础上进行头删)

 头文件:


 

 总结:

  • 顺序表的声明结构其实是一种结构体
  • 顺序表的底层结构是数组,所以更多的时候我们可以将顺序表当作数组来进行使用

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

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

相关文章

高通camx开源部分简介

camera整体框架 ISP Pipeline diagram Simple Model Camx and chi_cdk 整体框架 CtsVerifier, Camra Formats Topology of Camera Formats. Topology (USECASE: UsecaseVideo) Nodes List Links between nodes Pipeline PreviewVideo Buffer manager Create Destro…

定制自己的 Excel 界面 + 保存 Excel

文章目录 Excel 的界面自定义快速访问工具栏自定义功能区折叠或显示功能区自定义 Excel 的界面保存 Excel Excel 的界面 快速访问工具栏也可以放在功能区下方: 效果: 自定义快速访问工具栏 方法一: S1: S2: 方法二…

(c语言)经典bug

#include<stdio.h> //经典bug int main() { int i 0; int arr[10] {1,2,3,4,5,6,7,8,9,10}; for (i 0; i < 12; i) //越界访问 { arr[i] 0; printf("hehe\n"); } return 0; } 注&#xff1a;输出结果为死循…

geecg-uniapp 源码下载运行 修改端口号 修改tabBar 修改展示数据

APP体验&#xff1a; http://jeecg.com/appIndex技术官网&#xff1a; http://www.jeecg.com安装文档&#xff1a; 快速开始 JeecgBoot 开发文档 看云视频教程&#xff1a; 零基础入门视频官方支持&#xff1a; http://jeecg.com/doc/help 一&#xff0c;下载安装 源码下载…

信创之国产浪潮电脑+统信UOS操作系统体验3:使用 visual studio code搭建Python开发环境

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 一、引言 老猿原来在windows下开发python程序&#xff0c;要么使用python自带的IDLE&#xff0c;要么使用pycharm&#xff0c;IDLE用来开发很不方便&#xff0c;而pycharm对开发支持比较好&#xff0c;换成…

Angular学习笔记:路由

本文是自己的学习笔记&#xff0c;主要参考资料如下。 - B站《Angular全套实战教程》&#xff0c;达内官方账号制作&#xff0c;https://www.bilibili.com/video/BV1i741157Fj?https://www.bilibili.com/video/BV1R54y1J75g/?p32&vd_sourceab2511a81f5c634b6416d4cc1067…

【Java】微服务——Nacos配置管理(统一配置管理热更新配置共享Nacos集群搭建)

目录 1.统一配置管理1.1.在nacos中添加配置文件1.2.从微服务拉取配置1.3总结 2.配置热更新2.1.方式一2.2.方式二2.3总结 3.配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&#xff09;运行两个UserApplication&#xff0c;使用不同的pr…

大数据概述(林子雨慕课课程)

文章目录 1. 大数据概述1.1 大数据概念和影响1.2 大数据的应用1.3 大数据的关键技术1.4 大数据与云计算和物联网的关系云计算物联网 1. 大数据概述 大数据的四大特点&#xff1a;大量化、快速化、多样化、价值密度低 1.1 大数据概念和影响 大数据摩尔定律 大数据由结构化和非…

Observability:使用 OpenTelemetry 对 Node.js 应用程序进行自动检测

作者&#xff1a;Bahubali Shetti DevOps 和 SRE 团队正在改变软件开发的流程。 DevOps 工程师专注于高效的软件应用程序和服务交付&#xff0c;而 SRE 团队是确保可靠性、可扩展性和性能的关键。 这些团队必须依赖全栈可观察性解决方案&#xff0c;使他们能够管理和监控系统&a…

【面试经典150 | 矩阵】旋转图像

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;原地旋转方法二&#xff1a;翻转代替旋转 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带…

Flask实现注册登录模块

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 前言1.…

几道web题目

总结几道国庆写的web题目 [ACTF2020 新生赛]Include1 点进去发现就一个flag.php,源代码和抓包都没拿到好东西 结合题目猜是文件包含&#xff0c;构建payload ?filephp://filter/readconvert.base64-encode/resourceflag.php 得到base64编码过的flag&#xff0c;解码即可 此题…

Android---Class 对象在执行引擎中的初始化过程

一个 class 文件被加载到内存中的步骤如下图所示&#xff1a; 装载 装载是指 Java 虚拟机查找 .class 文件并生成字节流&#xff0c;然后根据字节流创建 java.lang.Class 对象的过程。 1. ClassLoader 通过一个类的全限定名&#xff08;包名类名&#xff09;来查找 .class 文件…

Linux多线程

文章目录 多线程多线程概念多线程优点多线程缺点线程和进程 Linux线程控制POSIX线程库线程的创建进程ID获取线程终止线程等待线程分离 总结 多线程 多线程概念 在Linux中&#xff0c;线程是进程内的执行单元。换句话说&#xff0c;线程是进程内部的子任务&#xff0c;它们共享…

入侵防御系统(IPS)网络安全设备介绍

入侵防御系统&#xff08;IPS&#xff09;网络安全设备介绍 1. IPS设备基础 IPS定义 IPS&#xff08;Intrusion Prevention System&#xff09;是一种网络安全设备或系统&#xff0c;用于监视、检测和阻止网络上的入侵尝试和恶意活动。它是网络安全架构中的重要组成部分&…

MyBatis中的ResultMap有什么作用

MyBatis是一款广泛使用的Java持久层框架&#xff0c;它简化了数据库访问和数据映射的工作。在MyBatis中&#xff0c;ResultMap是一个强大的工具&#xff0c;用于将数据库查询结果映射到Java对象上。本文将深入探讨MyBatis中的ResultMap&#xff0c;解释它的作用以及如何使用它来…

进程状态的理解

我们知道进程会有属于自己的PCB&#xff0c;便于操作系统的管理&#xff0c;而PCB结构体里面还有进程状态参数&#xff0c;类似于用一个变量标识对应的进程状态&#xff0c;就相当于将每个进程状态编号&#xff0c;而PCB中有一个变量存储当前进程状态所对应的编号&#xff0c;也…

解决WordPress升级后提示:无需升级,您的WordPress数据库已经是最新的了

问题描述 当升级了 WordPress 6.3 后&#xff0c;登录后台出现了提示&#xff1a;无需升级&#xff0c;您的WordPress 数据库已经是最新的了。并且无法进入后台了。 出现这个问题的原因可能是你网站开启了 Memcached 缓存。 如何验证是否开启了 Memcached 缓存&#xff1f;检…

php 安装mongodb扩展模块,rdkafka模块

mongodb mongodb扩展下载 选择php版本&#xff0c;根据报错提示&#xff0c;选择扩展对应的版本选择非安全进程将php_mongodb.dll放到php/ext目录下修改php.ini配置&#xff0c;添加extensionphp_mongodb.dll开启php_mongodb扩展&#xff0c;重启服务php -m 查看是否开启成功…