【数据结构】顺序表的深度剖析
🌇个人主页:平凡的小苏
📚学习格言:别人可以拷贝我的模式,但不能拷贝我不断往前的激情
🛸C语言专栏:https://blog.csdn.net/vhhhbb/category_12174730.html
🚀数据结构专栏:https://blog.csdn.net/vhhhbb/category_12211053.html
家人们更新不易,你们的👍点赞👍和⭐关注⭐真的对我真重要,各位路过的友友麻烦多多点赞关注,欢迎你们的私信提问,感谢你们的转发!
关注我,关注我,关注我,你们将会看到更多的优质内容!!
目录
1、顺序表概念
2、函数接口的实现
2.1、顺序表的初始化
2.2、顺序表的插入操作
2.3、顺序表的删除操作
2.4、顺序表的插入和删除的时间复杂度
2.5、线性表的顺序存储结构的优缺点
2.6、顺序表的查找
2.7、顺序表的销毁
3、顺序表源码
SList.c
SList.h
Test.c
1、顺序表概念
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素
- 线性表的存储结构,说白了,就是在内存中找块地儿,通过占位的形式,把一块内存空间给占了,然后把相同数据类型的数据元素依次存放在这块空地中。既然线性表的每个数据都相同,所以可以用C语言(其他语言也相同)的一维数组来实现顺序存储结构,即把第一个数据元素存到数组下标为0的位置中,接着把线性表相邻的元素存储在数组中相邻的位置。
2、函数接口的实现
来看线性表顺序存储的结构代码。
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#define InitCapa 4;//初始容量
typedef int SLDateType;
typedef struct SeqList
{SLDateType* a; //动态分配数组,存储数据元素int size;//数组元素个数int capacity;//数组容量的大小
}SeqList;
2.1、顺序表的初始化
void SeqListInit(SeqList* ps)
{assert(ps);ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 4);ps->size = 0;ps->capacity = InitCapa;
}
注:顺序表的初始化首先要动态分配容量为4的数组。数组元素的个数初始化为0.
2.2、顺序表的插入操作
我们现在来考虑,如果要实现线性的插入操作,即在顺序表的第i个位置插入新元素e,应该如何操作?
举个栗子,本来我们在春运时去买火车票,大家都排队排的好好的。这时来了一个抱着孩子的年轻妈妈,对着队伍中排在第三位的你说,“大哥,求求你帮帮忙,我家里母亲有病,我得急着回去看她,你看我还抱着孩子,这队伍这么长,你可否让我排在你的前面,你心一软,就同意了。这时,你必须得退后一步。骂声四起。但后面得人不清楚这加塞是怎么回事,没什么办法。
这个例子已经说明了线性表得顺序存储结构,在插入数据时得实现过程(如下图所示)
实现代码如下:
void CheckCapacity(SeqList* ps)
{if (ps->size == ps->capacity){SLDateType* tmp = (SLDateType*)realloc(ps->a,sizeof(SLDateType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail:");exit(-1);}ps->capacity *= 2;ps->a = tmp;}
}
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{assert(ps);CheckCapacity(ps);//检查容量函数,只要是插入元素得操作,都应该检查容量int end = ps->size-1;while (end >= pos)//每个元素往后移动{ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}
插入算法得思路:
(1)如果顺序表得长度大于等于数组长度,则动态增加容量;
(2)从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;
(3)将要插入得元素填入位置i处
(4)表长加1;
2.3、顺序表的删除操作
接着刚才的栗子。此时后面的人群意见都很大,都说怎么可以这样,不管什么原因,插队就是不行,有本事,找火车站开后门去。就在这时,远处跑来一胖子,对着这个美女喊,可找到你了,你这个骗子,还我钱。只见女子二话不说,突然就冲出了队伍,胖子追在其后。哦,原来她是倒卖火车票的黄牛,刚才还在装可怜。于是排队的人群,又像蠕虫一样,都向前移动了一步,骂声渐息,队伍又恢复了平静。
这就是顺序表的顺序存储结构的删除元素的过程实现(如下图所示)
实现代码如下:
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(ps->size);//如果容量为0,就抛出异常,不可以再删除int begin = pos;while (begin < ps->size-1){ps->a[begin] = ps->a[begin + 1];begin++;}ps->size--;
}
删除算法的思路:
(1)从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置;
(2)表长减1;
2.4、顺序表的插入和删除的时间复杂度
- 先看最好的情况,如果元素要插入到最后一个位置,或者删除最后一个元素时的时间复杂度为O(1),因为不需要移动元素。
- 最坏的情况呢,如果元素要插入到第一个位置或者删除第一个元素,此时的时间复杂度是多少呢?这就意味着要移动所有的元素向后或者向前,所以这个时间复杂度为O(n).
2.5、线性表的顺序存储结构的优缺点
优点:
- 无需为表示表中的元素之间的逻辑关系而增加额外的存储空间
- 可以快速地存取表中任意位置的元素
缺点:
- 插入和删除的操作需要移动大量的元素
2.6、顺序表的查找
实现代码如下:
int SeqListFind(SeqList* ps, SLDateType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){return i;}}return -1;
}
注:就是遍历查找的过程
2.7、顺序表的销毁
实现代码如下:
void SeqListDestroy(SeqList* ps)
{assert(ps);free(ps->a);ps->size = ps->capacity = 0;ps->a = NULL;
}
3、顺序表源码
SList.c
//SList.c
#include"SList.h"
void SeqListInit(SeqList* ps)
{assert(ps);ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 4);ps->size = 0;ps->capacity = InitCapa;
}void CheckCapacity(SeqList* ps)
{if (ps->size == ps->capacity){SLDateType* tmp = (SLDateType*)realloc(ps->a,sizeof(SLDateType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail:");exit(-1);}ps->capacity *= 2;ps->a = tmp;}
}
void SeqListPushBack(SeqList* ps, SLDateType x)
{assert(ps);CheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}
void SeqListPopBack(SeqList* ps)
{assert(ps->size);ps->size--;
}
void SeqListPopFront(SeqList* ps)
{//assert(ps);//assert(ps->size);//int begin = 0;//int end = 1;//while (end < ps->size)//{// ps->a[begin] = ps->a[end];// begin++;// end++;//}//ps->size--;SeqListErase(ps, 0);
}
void SeqListPushFront(SeqList* ps, SLDateType x)
{//assert(ps);//CheckCapacity(ps);//int end = ps->size;//int begin = ps->size - 1;//while (begin >= 0)//{// ps->a[end] = ps->a[begin];// begin--;// end--;//}//ps->a[0] = x;//ps->size++;SeqListInsert(ps, 0, x);
}
int SeqListFind(SeqList* ps, SLDateType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){return i;}}return -1;
}
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{assert(ps);CheckCapacity(ps);int end = ps->size-1;while (end >= pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(ps->size);int begin = pos;while (begin < ps->size-1){ps->a[begin] = ps->a[begin + 1];begin++;}ps->size--;
}
void SeqListPrint(SeqList* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}void SeqListDestroy(SeqList* ps)
{assert(ps);free(ps->a);ps->size = ps->capacity = 0;ps->a = NULL;
}
SList.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#define InitCapa 4;
typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;int size;int capacity;
}SeqList;// 对数据的管理:增删查改
void SeqListInit(SeqList* ps);
void SeqListDestroy(SeqList* ps);void SeqListPrint(SeqList* ps);
void SeqListPushBack(SeqList* ps, SLDateType x);
void SeqListPushFront(SeqList* ps, SLDateType x);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);
注:这里的尾插、头插、尾删、头删都是插入删除函数的复用
Test.c
#include"SList.h"
void TestSList()
{SeqList SL;SeqListInit(&SL);SeqListPushBack(&SL, 1);SeqListPushBack(&SL, 2);SeqListPushBack(&SL, 3);SeqListPushBack(&SL, 4);SeqListPrint(&SL);SeqListInsert(&SL, 1, 5);SeqListInsert(&SL, 1, 6);SeqListPrint(&SL);SeqListDestroy(&SL);
}
int main()
{TestSList();return 0;
}
好了!!!小编的分享到这里就结束了,想要继续了解数据结构的知识的,敬请期待博主的更新,有什么不足的地方请各位大佬多多指教!!!
相关文章:

【数据结构】顺序表的深度剖析
🌇个人主页:平凡的小苏 📚学习格言:别人可以拷贝我的模式,但不能拷贝我不断往前的激情 🛸C语言专栏:https://blog.csdn.net/vhhhbb/category_12174730.html 🚀数据结构专栏ÿ…...

当面试官问“你的SQL能力怎么样”时,怎么回答才不会掉进应聘陷阱?
在某平台看到一个比较实际的问题,在这里分享给职场新人。 SQL已经是职场最常用的一种编程语言,所以应聘技术或非技术岗位,都可能会被问道一个问题:你的SQL能力怎么样? 对于职场新人来说(SQL高手可以无视下…...

AI作画—中国画之山水画
山水画,简称“山水”,中国画的一种,描写山川自然景色为主体的绘画。山水画在我国绘画史中占有重要的地位。 山水画形成于魏晋南北朝时期,但尚未从人物画中完全分离。隋唐时始终独立,五代、北宋时趋于成熟,…...

Java:Java与Python — 编码大战
Java和Python是目前市场上最热门的两种编程语言,因为它们具有通用性、高效性和自动化能力。两种语言都有各自的优点和缺点,但主要区别在于Java 是静态类型的,Python是动态类型的。它们有相似之处,因为它们都采用了“一切都是对象”…...
山东专精特新各地市扶持政策
青岛市奖励政策:新认定为市隐形、省“专精特新”及省瞪羚、角兽的我市企业,分别给予50万元、30万元、50万元、300万元的一次性奖励。奖励金额:省级30万济南市奖励政策:对被认定的国家专精特新 “小巨人”企业一次性给予200万元奖励…...

持续事务管理过程中的事件驱动
比较官方的定义:事件驱动是指在持续事务管理过程中,进行决策的一种策略,即跟随当前时间点上出现的事件,调动可用资源,执行相关任务,使不断出现的问题得以解决,防止事务堆积。在计算机编程、公共…...

【手把手一起学习】(三) Altium Designer 20 原理图库添加元件
1 添加元件 元件符号是元件在原理图上的表现形式,主要由边框、管脚、名称等组成,原理图库中的元件管脚(顺序,间距等)与电子元件实物的引脚严格对应,绘制原理图库时,一定参考元件规格书和芯片数据手册中的说明…...
设计模式-行为型模式:观察者模式
目录 1、简介 2、组成部分 3、优缺点 4、使用场景 5、代码实现 1、简介 观察者模式是一种软件设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题对象发生变化时,所有的观察者对象都会得到…...

Springboot 为了偷懒,我封装了一个自适配的数据单位转换工具类
前言 平时做一些统计数据,经常从数据库或者是从接口获取出来的数据,单位是跟业务需求不一致的。 比如, 我们拿出来的 分, 实际上要是元 又比如,我们拿到的数据需要 乘以100 返回给前端做 百分比展示 又比如ÿ…...

正则表达式
当我们需要对字符串进行判断的时候,使用正则表达式能大大提高编程效率。比如,当我们需要找出所有“像邮箱”的字符串(包含"" "." ".com",且顺序一致),我们需要一个某种模式的…...

java进阶Map 集合
通过之前的学习我们知道Map是一个双列集合,就是以键值对的形式进行数据存储 java进阶—集合 Map 下面有 三个子接口,HashMap , HashTable 以及 TreeMap 提醒一点:Map不是Collection下的集合,Collection是单列集合&am…...

Java 方法超详细整理,适合新手入门
目录 一、什么是方法呢? 二、方法的优点 三、带返回值方法定义 语法: 示例: 四、带返回值方法调用 语法: 示例: 五、结果示例 一、什么是方法呢? Java方法是语句的集合,它们在一起执行…...

软考学习笔记(题目知识记录)
答案为 概要设计阶段 本题涉及软件工程的概念 软件工程的任务是基于需求分析的结果建立各种设计模型,给出问题的解决方案 软件设计可以分为两个阶段: 概要设计阶段和详细设计阶段 结构化设计方法中,概要设计阶段进行软件体系结构的设计&…...

2021.3.3idea创建Maven项目
首先new - project - 找到Maven 然后按下图操作:先勾选使用骨架,再找到Maven-archetype-webapp,选中,然后next填写自己想要创建的项目名,然后选择自己的工作空间①、选择自己下载的Maven插件②、选择选择Maven里的sett…...

ASP.NET MVC | 创建应用程序
目录 首先 NO.1 No.2 App_Data 文件夹 Content 文件夹 Controllers 文件夹 Models 文件夹 Views 文件夹 Scripts 文件夹 最后 首先 一步一步的来,电脑上需要安装vs2019软件,版本高低无所谓,就是功能多少而已。 长这样的࿰…...
思科设备命令讲解(超基础)
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放࿰…...

Qt-FFmpeg开发-保存视频流裸流(11)
Qt-FFmpeg开发-保存视频流裸流📀 文章目录Qt-FFmpeg开发-保存视频流裸流📀1、概述📸2、实现效果💽3、FFmpeg保存裸流代码流程💡4、主要代码🔍5、完整源代码📑更多精彩内容👉个人内容…...

Zebec官方辟谣“我们与Protradex没有任何关系”
近日,流支付协议Zebec Protocol在其官方推特上,发表了一个辟谣澄清声明。该条推特推文表示,“Zebec 与 Protradex 没有任何关系或产生关联。他们( Protradex )声称Zebec 生态正在支持他们,但这是错误的。随…...
BMS电池管理系统中的各种算法介绍
BMS电池管理系统 是一种用于电池组中的单个电池管理的系统,以确保其安全性、寿命和性能。BMS系统通过采集电池信息并对其进行分析,以确保电池组的正常运行。在BMS电池管理系统中,涉及到了许多算法,包括最大功率点追踪算法、SOC计算…...
stack Overflow 的使用
文章目录优雅的搜索1.1要在特定标签内搜索1.2搜索特定的短语1.3 限定检索位置1.4选择性屏蔽优雅的筛选搜索结果1. 返回的搜索筛选2. 特定时间段的帖子3. 精准的BOOL判断4. 其他的例子优雅的搜索 其实,在Stack OverFlow上的搜索方式,与国内的百度没什么大…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...