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

文章目录

  • 一、线性表
  • 二、顺序表
    • 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,一经查实,立即删除!

相关文章

Javascript高级—深浅拷贝

浅拷贝 浅拷贝是拷贝第一层的拷贝 使用Object.assign解决这个问题。 let a {age: 1 } let b Object.assign({}, a) a.age 2 console.log(b.age) // 1通过展开运算符 ... 来实现浅拷贝 let a {age: 1 } let b {...a}; a.age 2; console.log(b.age) // 1深拷贝 简单的…

【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 小波变换去噪完整代码总结参考文献…

(十)Python字典基本操作

与列表和元组有所不同&#xff0c;字典是另一种可变容器模型&#xff0c;且可存储任意类型的对象。 一、字典对象常用操作 字典的对象使用大括号{}将元素列出。字典的元素排列并没有一定的顺序&#xff0c;因为可以使用键值来取得该元素。 hh{"名称":"葡萄&q…

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

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

Oracle RAC的thread

参考文档&#xff1a; Real Application Clusters Administration and Deployment Guide 3 Administering Database Instances and Cluster Databases Initialization Parameter Use in Oracle RAC Table 3-3 Initialization Parameters Specific to Oracle RAC THREAD Sp…

Chat GPT英文学术写作指令

目录 Chat GPT英文学术写作指令 Chat GPT英文学术写作指令 1."为我捉供一些建议和技巧,以提高我的学术写作质最和风格" (Provide me with some suggestions andtips to improve the quality andstyleofmyacademic writing.) 2."帮我提写一个清晰而有逻辑的…

Springboot集成syslog+logstash收集日志到ES

Springboot集成sysloglogstash收集日志到ES 1、背景 Logstash 是一个实时数据收集引擎&#xff0c;可收集各类型数据并对其进行分析&#xff0c;过滤和归纳。按照自己条件分析过滤出符合的数据&#xff0c;导入到可视化界面。它可以实现多样化的数据源数据全量或增量传输&…

函数式编程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 …

golang 泛型 middleware 设计模式: 一次只做一件事

golang 泛型 middleware 设计模式: 一次只做一件事 1. 前言 本文主要介绍 在使用 gRPC 和 Gin 框架中常用的 middleware 设计模式 还有几种叫法 装饰器模式Pipeline 模式 设计思想: 10 个 10 行函数, 而不是 1 个 100 行函数一次只做一件事, 而不一次做多件事单一职责 2…

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.使用背景 我们在进行深度学习训练的时候&…

「Mac玩转仓颉内测版3」入门篇3 - Cangjie的基本语法与结构

本篇将深入探讨Cangjie语言的基本语法与结构。这些基础知识为编写高效、可维护的代码奠定了坚实基础。通过理解语句结构、表达式、注释及数据类型&#xff0c;能够更自信地使用Cangjie进行编程。 关键词 Cangjie基本语法语句结构表达式注释数据类型控制结构 一、基本语法 1.…

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

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

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

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

使用Golang实现开发中常用的【实例设计模式】

使用Golang实现开发中常用的【实例设计模式】 设计模式是解决常见问题的模板&#xff0c;可以帮助我们提升思维能力&#xff0c;编写更高效、可维护性更强的代码。 单例模式&#xff1a; 描述&#xff1a;确保一个类只有一个实例&#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;请编写一个函数&…