【数据结构】线性表——顺序表

文章目录

  • 一、线性表
  • 二、顺序表
    • 2.1概念及结构
    • 2.2、顺序表接口实现
      • 2.2.1、顺序表的动态存储
      • 2.2.2、顺序表初始化
      • 2.2.3、检查空间判断进行增容
      • 2.2.4、顺序表尾插、尾删
      • 2.2.5、顺序表头插、头删
      • 2.2.6、顺序表查找
      • 2.2.7、顺序表在pos位置插入x
      • 2.2.8、顺序表删除pos位置的值
      • 2.2.9、顺序表销毁
      • 2.2.10、顺序表打印
  • 三、顺序表的劣势


一、线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表逻辑上是线性结构,也就说是连续的一条直线(如图一)。但是在物理结构上并不一定连续的(如图二)。线性表物理上存储时,通常以数组和链式结构的形式存储。(假设在32位机器上)
在这里插入图片描述
在这里插入图片描述


二、顺序表

2.1概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。(如下图)在这里插入图片描述

  2. 动态顺序表:使用动态开辟的数组存储。在这里插入图片描述

说白了顺序表就是数组😆没想到把~意不意外
虽说顺序表就是数组,但是也不能说顺序表没用,在高级的储存单元里面(如二叉树)底层就是使用顺序表的。

2.2、顺序表接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

2.2.1、顺序表的动态存储

函数命名规则借鉴CPP的stl库进行命名。

首先创建一个结构体,用于储存顺序表结构。

typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;int size;int capacity;
}SeqList;
  • typedef int SLDateType;把顺序表结构的类型重命名为:SLDateType。若将来如果要改变数据顺序表内容的结构类型。可以极为方便的改变。
  • 在结构体中定义了。顺序表的总体大小和当前容量。以便确认是否需要扩容。
  • 定义的SLDateType*用于接收动态开辟的内存。
  • size是顺序表的大小。
  • capacity是顺序表当前的元素数量。

2.2.2、顺序表初始化

void SeqListInit(SeqList* ps) {SLDateType* arr = (SLDateType*)malloc(sizeof(SLDateType) * 2);if (arr == NULL) {perror("malloc in SeqListInit of arr::");}ps->a = arr;ps->size = 2;ps->capacity = 0;
}
  • 因为顺序表的结构体是用户自己开辟没有进行顺序表存储空间内存划分的。所以需要把顺序表的表存储空间进行初始化。
  • 默认开辟两个空间。
  • 在成功开辟后。把size设置为2。capacity设置为0。

2.2.3、检查空间判断进行增容

void CheckCapacity(SeqList* ps) {if (ps->capacity == ps->size) {SLDateType* arr = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * ps->size * 2);if (arr == NULL) {perror("realloc in SeqListPushBack");}ps->a = arr;ps->size *= 2;}
}
  • 每次进行插入都需要判断空间是否足够,所以,需要提前完成检查空间函数。
  • 每次扩容扩二倍。

2.2.4、顺序表尾插、尾删

void SeqListPushBack(SeqList* ps, SLDateType x) {assert(ps);CheckCapacity(ps);//int i = ps->capacity;(ps->a)[ps->capacity] = x;ps->capacity++;
}

与数组增添并无二样。

void SeqListPopBack(SeqList* ps) {assert(ps && ps->capacity);ps->capacity--;
}
  • 只要把当前数据。进行减减。无需把顺序表中的内容进行删除。因为再次尾插数据,就会把之前的数据覆盖。

2.2.5、顺序表头插、头删

void SeqListPushFront(SeqList* ps, SLDateType x) {assert(ps);CheckCapacity(ps);memmove(((ps->a) + 1), ps->a, sizeof(SLDateType) * ps->capacity);ps->a[0] = x;ps->capacity++;
}
  • 顺序表的头插需要把全部数据往后移动一位。
  • 移动完成后就插入数据到头部空位。
void SeqListPopFront(SeqList* ps) {assert(ps && ps->capacity);ps->capacity--;memmove(ps->a, ((ps->a) + 1), sizeof(SLDateType) * ps->capacity);
}
  • 头删只需要把后面一位的数据全部往前移动一位。即可覆盖首元素的数据。

2.2.6、顺序表查找

int SeqListFind(SeqList* ps, SLDateType x) {assert(ps && ps->capacity);for (int i = 0; i < ps->capacity; i++) {if (ps->a[i] == x) {return i;}}return -1;
}
  • 与数组查找数据一样,循环遍历即可。

2.2.7、顺序表在pos位置插入x

void SeqListInsert(SeqList* ps, int pos, SLDateType x) {assert(ps && ps->capacity);CheckCapacity(ps);memmove(ps->a + pos, ps->a + pos - 1, sizeof(SLDateType) * (ps->capacity - pos + 1));ps->a[pos - 1] = x;ps->capacity++;
}
  • 找到对应位置后,从当前位置位置到数据结尾的内容全部向后移动一位。然后再在该位置进行数据的赋值。

2.2.8、顺序表删除pos位置的值

void SeqListErase(SeqList* ps, int pos) {assert(ps && ps->capacity);memmove(ps->a + pos - 1, ps->a + pos, sizeof(SLDateType) * (ps->capacity - pos + 1));ps->capacity--;}
  • 找到需要删除的pos位置后。把pos后一位的内容全部向前移动一位即可把pos值原先的内容覆盖。做到删除pos位置的值

2.2.9、顺序表销毁

void SeqListDestroy(SeqList* ps) {assert(ps && ps->a);free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}
  • 直接把动态开辟的内存释放掉,然后再把ps结构体中全部内容赋为空或零值。

2.2.10、顺序表打印

void SeqListPrint(SeqList* ps) {assert(ps && ps->a);for (int i = 0; i < ps->capacity; i++) {printf("%d ", ps->a[i]);}printf("\n");
}
  • 与数组的循环打印并无二样。
  • 把循环结束条件定为capacity,这样做可以把尾删的数据不再打印数据中。

三、顺序表的劣势

  1. 中间/头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

以上就是本章所有内容。若有勘误请私信不才。万分感激💖💖 如果对大家有帮助的话,就请多多为我点赞收藏吧~~~💖💖
请添加图片描述

ps:表情包来自网络,侵删🌹

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

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

相关文章

【Matlab算法】MATLAB实现基于小波变换的信号去噪(附MATLAB完整代码)

MATLAB实现基于小波变换的信号去噪 结果图前言正文1. 小波变换理论基础1.1 小波变换的数学模型1.2 离散小波变换原理2. 信号去噪方法2.1 去噪算法流程2.2 阈值处理方法3. 核心函数解析3.1 wavedec函数3.2 wthresh函数代码实现4.1 信号生成4.2 小波变换去噪完整代码总结参考文献…

神经网络基础--什么是正向传播??什么是方向传播??

前言 本专栏更新神经网络的一些基础知识&#xff1b;这个是本人初学神经网络做的笔记&#xff0c;仅仅堆正向传播、方向传播进行了讲解&#xff0c;更加系统的讲解&#xff0c;本人后面会更新《李沐动手学习深度学习》&#xff0c;会更有详细讲解;案例代码基于pytorch&#xf…

函数式编程Stream流(通俗易懂!!!)

目录 1.Lambda表达式 1.1 基本用法 1.2 省略规则 2.Stream流 2.1 常规操作 2.1.1 创建流 2.1.2 中间操作 filter map distinct sorted limit ​编辑skip flatMap 2.1.3 终结操作 foreach count max&min collect anyMatch allMatch noneMatch …

AMD-OLMo:在 AMD Instinct MI250 GPU 上训练的新一代大型语言模型。

AMD-OLMo是一系列10亿参数语言模型&#xff0c;由AMD公司在AMD Instinct MI250 GPU上进行训练&#xff0c;AMD Instinct MI250 GPU是一个功能强大的图形处理器集群&#xff0c;它利用了OLMo这一公司开发的尖端语言模型。AMD 创建 OLMo 是为了突出其 Instinct GPU 在运行 “具有…

使用服务器时进行深度学习训练时,本地必须一直保持连接状态吗?

可以直接查看方法&#xff0c;不看背景 1.使用背景2. 方法2.1 screen命令介绍2.2 为什么要使用screen命令2.3 安装screen2.4 创建session2.5 查看session是否创建成功2.6 跳转进入session2.7 退出跑代码的session2.8 删除session 1.使用背景 我们在进行深度学习训练的时候&…

深入了解区块链:Web3的基础架构与发展

在数字时代的浪潮中&#xff0c;区块链技术正逐渐成为Web3的重要基础&#xff0c;重新定义互联网的结构和用户体验。Web3不仅是一个全新的网络阶段&#xff0c;更代表了一种去中心化的理念&#xff0c;强调用户主权和数据隐私。本文将深入探讨区块链在Web3中的基础架构、技术特…

华为大变革?仓颉编程语言会代替ArkTS吗?

在华为鸿蒙生态系统中&#xff0c;编程语言的选择一直是开发者关注的焦点。近期&#xff0c;华为推出了自研的通用编程语言——仓颉编程语言&#xff0c;这引发了关于仓颉是否会取代ArkTS的讨论。本文将从多个角度分析这两种语言的特点、应用场景及未来趋势&#xff0c;探讨仓颉…

【C++笔记】C++三大特性之继承

【C笔记】C三大特性之继承 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】C三大特性之继承前言一.继承的概念及定义1.1 继承的概念1.2继承的定义1.3继承基类成员访问方式的变化1.4继承类模板 二.基类和派生类间的转…

Windows搭建流媒体服务并使用ffmpeg推流播放rtsp和rtmp流

文章目录 搭建流媒体服务方式一安装mediamtx启动meidamtx关闭meidamtx 方式二安装ZLMediaKit启动ZLMediaKit关闭ZLMediaKit 安装FFmpeg进行推流使用FFmpeg进行rtmp推流使用VLC播放rtmp流停止FFmpeg的rtmp推流使用FFmpeg进行rtsp推流使用VLC播放rtmp流停止FFmpeg的rtsp推流 本文…

Polybase要求安装orcale jre 7

在安装SQL SERVER时&#xff0c;遇到以下情况&#xff1a;polybase要求安装orcale jre 7更新 51或更高版本 不想安装JDK7。可通过不安装polybase的功能来实现下一步的安装。 1. 点击上一步&#xff0c;回到功能选择的设置界面中。 2. 然后在功能选择窗口中&#xff0c;取消勾选…

深入理解计算机系统 3.7 缓冲区溢出

3.7.1 数据对齐 许多计算机系统对基本数据类型的合法地址做出了一些限制&#xff0c;要求某种类型对象的地址必须是某个值K(通常是2、4或8)的倍数。这种对齐限制简化了形成处理器和内存系统之间接口的硬件设计。例如&#xff0c;假设一个处理器总是从内存中取8个字节&#xff…

代码随想录刷题记录(二十七)——55. 右旋字符串

&#xff08;一&#xff09;问题描述 55. 右旋字符串&#xff08;第八期模拟笔试&#xff09;https://kamacoder.com/problempage.php?pid1065字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k&#xff0c;请编写一个函数&…

QT打包应用程序文件步骤

QT应用程序&#xff08;.exe&#xff09;打包复制到其他电脑 在QT程序在自己电脑编译好了后&#xff0c;需要打包给其他人。这里介绍一下详细步骤&#xff1a; 确定编译器 搜了很多相关的打包教程&#xff0c;但是还是会出现“应用程序无法正常启动(0xc000007b)”这类错误。经过…

我谈维纳(Wiener)复原滤波器

Rafael Gonzalez的《数字图像处理》中&#xff0c;图像复原这章内容几乎全错。上篇谈了图像去噪&#xff0c;这篇谈图像复原。 图像复原也称为盲解卷积&#xff0c;不处理点扩散函数&#xff08;光学传递函数&#xff09;的都不是图像复原。几何校正不属于图像复原&#xff0c…

10款音频剪辑推荐!!你的剪辑好帮手!!

在如今的数据化浪潮中&#xff0c;工作已经采用了线上线下相结合。我的工作就需要借助一些剪辑工具&#xff0c;来实现我对音频工具的剪辑。我初次接触到音频剪辑也是因为工作需求&#xff0c;从起初我只是一个音频剪辑的小白&#xff0c;这些工具的协助。吸引着我。对于这些工…

Rocky、Almalinux、CentOS、Ubuntu和Debian系统初始化脚本v9版

Rocky、Almalinux、CentOS、Ubuntu和Debian系统初始化脚本 Shell脚本源码地址&#xff1a; Gitee&#xff1a;https://gitee.com/raymond9/shell Github&#xff1a;https://github.com/raymond999999/shell脚本可以去上面的Gitee或Github代码仓库拉取。 支持的功能和系统&am…

Scrapy搭配Selenium爬取豆瓣电影250排行榜动态网页数据

参考CSDN博客&#xff1a;https://blog.csdn.net/qq_43213783/article/details/113063557 2024年11月11日实现。 创建movie_douban爬虫项目&#xff1a; scrapy startproject movie_douban 进入spiders&#xff1a; cd movie_douban/movie_douban/spiders 创建doubanMovieSpi…

想定制RK3566/3568安卓11开机logo吗?触觉智能Purple Pi OH来教你

本文介绍瑞芯微RK3566/RK3568主板/开发板安卓Android11系统替换开机Logo的方法&#xff0c;使用触觉智能Purple Pi OH鸿蒙开发板演示&#xff0c;搭载了瑞芯微RK3566芯片&#xff0c;4核1.8Ghz1T算力NPU&#xff1b;类树莓派设计&#xff0c;Laval社区主荐&#xff0c;已适配全…

【AliCloud】ack + ack-secret-manager + kms 敏感数据安全存储

介绍 ack-secret-manager支持以Kubernetes Secret实例的形式向集群导入或同步KMS凭据信息&#xff0c;确保您集群内的应用能够安全地访问敏感信息。通过该组件&#xff0c;您可以实现密钥数据的自动更新&#xff0c;使应用负载通过文件系统挂载指定Secret实例来使用凭据信息&a…

网页设计平台:6个技术亮点

想要创建个人或商业网站来分享知识或推广商品吗&#xff1f;这篇文章将为你介绍6个免费的网页制作平台&#xff0c;帮助你即使没有编程基础也能快速、轻松地搭建出专业且引人注目的网站。让我们一起探索这些平台&#xff0c;发现它们的特色和优势。 即时设计 即时设计是一个云…