【数据结构】顺序表的深度刨剖析
前言:
在上一篇文章中,我们已经对数据结构有了一定了解,我们可以通过优化空间复杂度或者时间复杂度从而提高我们程序运行或存储速率。至此我们就知道了数据结构的重要性,所以今天我们将要了解和学习一种实用的数据结构——线性表。
一、线性表概述:
线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列,是最基本、最简单也最常用的一种数据结构。
线性表中的数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其他数据元素都是首尾相连的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是线性表,但存储层次上属于链式存储,是把最后一个数据元素的尾指针指向了首位节点)
线性表在逻辑上是线性结构,但是在物理结构并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。 常见的线性表:顺序表、链表、栈、队列、字符串等等。

二、顺序表:
了解完线性表后,就要进入我们今天的主题,我们今天最主要学的的是线性表中的顺序表。
概念和结构:
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,并在数组上完成数据的增删查改。其本质就是数组,但与数组不同的是:顺序表在其数组本质的基础上,还要求数据连续存储,不能跳跃或间隔存储。
顺序表一般可分为两类:
静态顺序表:使用一定长度的数组存储元素。但是静态顺序表存在很明显的缺陷,即大小固定,数据少了就会造成空间浪费,数据多了空间不够导致不能存储。
#define N 10
typedef int SLDataType;
typedef struct SeqList
{SLDataType arr[N];int size;
}SeqList;
动态顺序表:使用动态开辟的数组存储元素。动态顺序表很好弥补了静态顺序表的弊端,使空间申请变得灵活,我们可根据情况进行扩容操作从而申请到合适大小的空间。
typedef int SLDataType;
typedef struct SeqList
{SLDataType* a;int size;inte capacity;
}SeqList;
2、顺序表的实现:
现在开始,我们开始实现顺序:
①初始化顺序表:
void SeqListInit(SeqList* ps)
{assert(ps);//防止传入空指针;ps->a = malloc(sizeof(SLDateType) * INIT_CAPACITY);if (ps->a == NULL){perror("malloc fail");}ps->size = 0;ps->capacity = INIT_CAPACITY;}
②销毁顺序表:
void SeqListDestroy(SeqList* ps)
{assert(ps);//防止传入空指针;free(ps->a);ps->a = NULL;ps->capacity = ps->size=0;
}
③顺序表尾插:
尾插即在最后一个元素下一个位置上插入元素,也就是size的位置上,插入之后,总数据+1也就是size++。
void SeqListPushBack(SeqList* ps, SLDateType x)
{assert(ps);//检查是否需要扩容if (ps->size == ps->capacity){SLDateType* tmp = (SLDateType)realloc(ps->a, sizeof(SLDateType) * ps->capacity + 5);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity += 5;}ps->a[ps->size++] = x;
}
④顺序表尾删:
尾删就是把最后一个元素删除,所以size不能为0,删除之后总数据减一,size--。
void SeqListPopBack(SeqList* ps)
{assert(ps);assert(ps->size > 0);ps->size--;}
⑤顺序表头插:
头插也就是在第一个元素前面插入第一个元素,因为我们使用数组实现的顺序表所以头插需要挪动元素。
插入之后,总数据+1也就是size++。
void SeqListPushFront(SeqList* ps, SLDateType x)
{assert(ps);if (ps->size == ps->capacity){SLDateType* tmp = (SLDateType)realloc(ps->a, sizeof(SLDateType) * ps->capacity + 5);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity += 5;}for (int i = ps->size; i > 0; i--){ps->a[i] = ps->a[i - 1];}ps->a[0] = x;ps->size++;}
⑥顺序表的头删除:
与头插类似,同样需要挪动元素,只不过挪动方向变了,头插是往后挪,头删是往前挪,删除之后总数据减一,size--。
void SeqListPopFront(SeqList* ps)
{assert(ps);int count = 1;for (count = 1; count <= ps->size; count++){ps->a[count - 1] = ps->a[count];}ps->size--;
}
⑦打印顺序表:
void SeqListPrint(SeqList* ps)
{if (ps->size == 0){printf("顺序表为空");return;}for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}
⑧顺序表中查找:
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;}
}
⑨在指定下标插入:
插入之后,总数据+1也就是size++。
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);if (ps->size == ps->capacity){SLDateType* tmp = (SLDateType)realloc(ps->a, sizeof(SLDateType) * ps->capacity + 5);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity += 5;}for (int i = ps->size; i > pos;i--){ps->a[i] = ps->a[i - 1];}ps->a[pos] = x;ps->size++;
}
⑩删除指定下标位置元素:
删除之后总数据减一,size--。
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos <= ps->size);for (int i = pos; i < ps->size-1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;}
总结:
顺序表相对来说比较简单,很重要一点就是在执行操作时,要思考是否要进行断言操作,避免使用空指针。文章到此就结束啦。
相关文章:

【数据结构】顺序表的深度刨剖析
前言:在上一篇文章中,我们已经对数据结构有了一定了解,我们可以通过优化空间复杂度或者时间复杂度从而提高我们程序运行或存储速率。至此我们就知道了数据结构的重要性,所以今天我们将要了解和学习一种实用的数据结构——线性表。…...

Unity 之 使用原生UGUI实现随手移动摇杆功能经典实例
Unity 之 使用原生UGUI实现随手移动摇杆功能实现效果一,实现思路1.1 原理解析1.2 思路概述二,实现代码2.1 随手落下2.2 摇杆转动三,源码分享3.1 场景搭建3.2 完整代码3.3 实现效果实现效果 本文最终实现效果: 一,实现…...

Linux内核源代码概述
Linux内核源代码非常庞大,截止到2015年据统计代码总量就已经超过1500万行(LOC,Line of Code),看代码总量非常吓人,具体看这1500万行代码的大致分布情况如下图。 显然占比最大的drivers和arch目录下的代码合…...

Nginx 教程-动静分离
一、Nginx 动静分离理论1、概念今天学习和梳理Nginx动静分离,动静分离是将网站静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,之所以要进行动静分离,其一为了提高前端…...

自己设计的网站,如何实现分页功能?(详细代码+注释)
目录 前言 实现分页功能 需求分析 客户端开发 服务器开发 前后端交互——两种前端得到 文章总页数 的方法,那种更合适? 前言 你在设计网站的时候是否有过这样的烦恼:“我设计的网站怎么就是从上到下一条线内容全部展开,一点都…...

STM32F407控制微型推拉式电磁铁(通过继电器)
1、继电器 继电器相当于开关,单片机通过io口高低电平的控制来控制继电器的开闭。采用继电器的好处除了能够用低电压控制高电压(如32单片机控制220V的电压)外,还可以防止电流反冲,弄烧单片机。 本文采用3.3v的电磁铁&am…...

VS Code工作区用法
背景VS Code可以通过"文件/打开文件夹"来打开本地项目,但是想要打开多个项目便需要来回切换,比较费劲。此时就可以使用工作区功能,将不同的项目放置到同一个工作区中,这样切换项目的时候就会非常方便。操作方法打开其中…...

Mybatis-Plus SQLFeatureNotSupportedException: getObject with type问题解决
问题描述: Error attempting to get column modify_time from result set. Cause: java.sql.SQLFeatureNotSupportedException: getObject with type ; getObject with type; nested exception is java.sql.SQLFeatureNotSupportedException: getObject with type…...
Unity | 发布Android的那些事儿
1.使用UnityWebRequest获取StreamingAssets中的json文件(1)直接根据不同平台指定url路径IEnumerator AITalPredZhanHui(){string url;string fileName "girl.json"; #if UNITY_EDITOR || UNITY_STANDALONEurl "file://" Applicat…...
git为什么要先commit,然后pull,最后再push?而不是commit完直接push?
情况是这样的,现在远程有一个仓库,分支就一个,是master。然后我本地的仓库是从远程的master上clone下来的。大家都是clone下来,再在自己本地改好,再commit然后pull然后push,大家都是这么做的。那么现在问题…...
若依框架----源码分析(@RateLimiter)
若依作为最近非常火的脚手架,分析它的源码,不仅可以更好的使用它,在出错时及时定位,也可以在需要个性化功能时轻车熟路的修改它以满足我们自己的需求,同时也可以学习人家解决问题的思路,提升自己的技术水平…...

页面的重排和重绘?
思路: 网页渲染HTML文件到浏览器的过程->定义->如何优化网页渲染HTML文件到浏览器的过程HTML 文件通过HTML解析器解析生成DOM树;CSS文件通过CSS解析器生成CSSOM树;DOM树和CSSOM树生成渲染树(render tree)&#x…...
人脸检测-python和c++实现
人脸检测是计算机视觉领域中的一个重要应用,其目的是从图像或视频中自动检测出其中的人脸,并对其进行识别、跟踪等操作。人脸检测技术已经广泛应用于安防、人机交互、娱乐等领域,具有广泛的应用前景。 人脸检测的基本思路可以分为以下几个步骤: 图像预处理:首先需要对输入…...

PowerJob源码环境搭建
一、IEDA导入PowerJob源码 gitgithub.com:PowerJob/PowerJob.gitPowerJob 由调度服务器(powerjob-server)和执行器(powerjob-worker)两部分组成 powerjob-server 负责提供 Web 服务和完成任务的调度powerjob-worker 则负责执行用…...

天梯赛刷题小记 —— L2
最近在重刷 天梯赛,浅浅记录一下,进入L2阶段了 L2-001 紧急救援 解题思路:典型的dijkstra模板题,带路径记录与权重,方案数记录,解析出过 Dijkstra(兼路径) #include <bits/stdc.h> #define inf…...

Prometheus监控实战系列十九:监控Kubernetes集群(上)
Kuberentes是一款开源的容器编排产品,由Google开发后发布到社区,并在2015年将该项目捐献给了云原生基金会(Cloud Native Computing Foundation)。从2014年第一个版本发布以来,Kubernetes便迅速获得开源社区的追捧&…...
番茄学习法——亲测超级好用
今天给大家分享下我最近使用的学习方法,真的非常好用!大家用起来! 在日常的学习和工作中,我们经常会遇到一些难以克服的问题:分心、效率低下、焦虑等。为了帮助人们更好地学习和工作,一些学习方法和工具应运…...

vue 项目中使用高德地图
一、账号准备 首先,需要注册并登录高德地图开放平台,申请密钥。操作指引:高德地图开放平台 二、安装高德地图加载器 npm 安装: npm i amap/amap-jsapi-loader --save或者 yarn 安装: yarn add amap/amap-jsapi-loa…...
【每日一题】病人排队
题目描述小理是个热爱生活的孩子。病人登记看病,小理想编写一个程序,将登记的病人按照以下原则排出看病的先后顺序:1. 老年人(年龄 ≥≥ 60岁)比非老年人优先看病。2. 老年人按年龄从大到小的顺序看病,年龄…...

【数据结构】链表OJ题
目录面试题 02.04 分割链表剑指 Offer II 027 回文链表160 相交链表141 环形链表142 环形链表 II138 复制带随机指针的链表面试题 02.04 分割链表 定义lesshead和greaterhead链接小于和大于等于k的值分别设置哨兵位和尾节点指针最后将两表去除哨兵位再链接 struct ListNode* p…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...