拿捏 顺序表(1)

目录

  • 1. 顺序表的分类
  • 2. 顺序表实现
  • 3. 顺序表实现完整代码
  • 4. 总结

前言:
一天xxx想存储一组数据, 并且能够轻松的实现删除和增加, 此时数组大胆站出, 但是每次都需要遍历一遍数组, 来确定已经存储的元素个数, 太麻烦了, 于是迎来了顺序表不屑的调侃: 数组你不行啊…

顺序表是一种常见的数据结构,它是由一组连续的存储单元组成的线性表。顺序表的优点是可以随机存取,即可以通过下标直接访问元素,查找和更新操作的时间复杂度为O(1)。同时,顺序表还可以通过动态扩容来实现自动调整大小,使得其具有灵活性。本文将介绍顺序表的定义、操作以及一些应用场景,帮助读者更好地理解和应用顺序表。

博客主页: 酷酷学!!! 感谢关注❤


正文开始

1. 顺序表的分类

顺序表的底层结构就是数组,对数组的封装,实现了常用的增删改查等接,
也就是顺序表是站在数组的肩膀上飞黄腾达.

顺序表又分为静态和动态

静态顺序表:
概念:使用定长数组存储元素

在这里插入图片描述
这里有个缺陷: 空间给少了不够用, 给多了造成浪费, 于是直接pass

动态顺序表 :
在这里插入图片描述
弥补了缺陷: 就你了,下面进行实现

2. 顺序表实现

第一步:
首先完成顺序表我们分成三个源文件来完成, 这样看起来代码更舒服

在这里插入图片描述

//我们这里创建三个源文件
//Seqlist.h 用来放文件的声明已经类型的定义
//Seqlist.c 用来放顺序表实现的方法
//test.c 用来进行代码测试

第二步:
我们直接在头文件声明结构体, 并且进行一些函数的声明

//直接在.h包含头文件, 以方便我们直接使用
#pragma once//以下声明只会包含一次, 提高代码效率
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SeqDataType;//自定义类型名,方便后期修改存储数据类型typedef struct SeqList
{SeqDataType* arr;int size;int capacity;
}SL;//声明结构体类型,自定义类型名为SLvoid SLInit(SL* ps);//初始化函数声明
void SLDestory(SL* ps);//销毁函数声明void SLCheckCapacity(SL* ps);//判断空间容量函数声明
void SLPushBack(SL* ps, SeqDataType x);//尾插汉书声明
void SLPushFront(SL* ps, SeqDataType x);//头插函数声明void SLprint(SL ps);//打印内容函数void SLPopBack(SL* ps);//尾删函数
void SLpopFront(SL* ps);//头删函数

第三步:
来到.Seqlist.c 封装各类函数

初始化:

void SLInit(SL* ps)
{assert(ps);//不可以给我传个NULL哦,之后每次参数为指针最好都断言一下ps->arr = NULL;ps->size = ps->capacity = 0;
}

销毁操作:

void SLDestory(SL* ps)
{assert(ps);if (ps->arr)//如果arr里面有内容,那么就释放这块内存, 我们之后会动态开辟内存{free(ps->arr);}ps->arr = NULL;//避免成为野指针ps->capacity = ps->size = 0;
}

第四步:
前期准备工作已完成, 下面进行代码高速

首先完成怎么插入, 但是有一个问题: 如果这个顺序表大小为0, 或者大小满了的情况下我们怎么插入呢? 所以我们要进行先判断空间容量, 但是后期我们可能还要进行头插操作是不是也要判断一次, 好麻烦欸, 干脆直接封装成函数, 这样更简洁

于是乎:

void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity)//没空间或者满了,这不就是需要扩容吗{int Newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//如果第一次没空间让它开辟个四块内存,不够再成倍给SeqDataType* tmp = (SeqDataType*)realloc(ps->arr, Newcapacity * sizeof(SeqDataType));//不要忘记realloc申请失败可是会返回NULL,直接赋值会造成内存泄露,不如交给临时变量if (tmp == NULL){perror("realloc fail");exit(1);}ps->arr = tmp;//没问题再给ps->arrtmp = NULL;//不需要的指针变量可以拴起来ps->capacity = Newcapacity;//修改空间容量大小}
}

第五步:实现头插尾插

先看尾插(因为比较简单)

//尾插
void SLPushBack(SL* ps, SeqDataType x)
{assert(ps);SLCheckCapacity(ps);ps->arr[ps->size++] = x;
}//寥寥三行,这不比数组简单?

头插:

void SLPushFront(SL* ps, SeqDataType x)
{assert(ps);SLCheckCapacity(ps);for (int i = ps->size; i>0; i--){ps->arr[i] = ps->arr[i-1];//最后一次ps->arr[1] = ps->arr[0]}//参考下图ps->arr[0] = x;ps->size++;
}

在这里插入图片描述

我们是不是需要由左图变成右图呀, 给第一个位置空出来

第六步:
当然了, 我们也可以实验一下前面的代码正不正确,于是乎我们可以让控制台打印, 不妨写如下函数:

void SLprint(SL ps)
{for (int i = 0; i < ps.size; i++){printf("%d ", ps.arr[i]);}printf("\n");
}

我举个栗子:
我们不妨在test.c里面写上如下代码,看看成功与否

#include "Seqlist.h"int main()
{SL s;SLInit(&s);SLPushBack(&s, 4);SLPushBack(&s, 3);SLPushBack(&s, 2);SLPushBack(&s, 1);SLprint(s);SLPushFront(&s, 3);SLPushFront(&s, 4);SLprint(s);

我只能说轻松拿捏:
在这里插入图片描述

最后一步:

实现删除操作:

先来尾删(因为简单)

void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);ps->size--;
}//想一想为什么这么简单,就是这么简单,因为最后那个位置直接可以被其它值覆盖

接着头删:

void SLpopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0; i <=ps->size-2 ; i++){ps->arr[i] = ps->arr[i + 1];//最后一次arr[size-2] = arr[size-1]}//看下图:ps->size--;
}

这里我们依旧需要由左边变成右边想想看是不是
在这里插入图片描述

okok,到此我们顺序表已经全部结束, 欲知后事如何,请见下回讲解,点个关注不迷路

下面直接开始今天的代码测试

#include "Seqlist.h"int main()
{SL s;SLInit(&s);SLPushBack(&s, 4);SLPushBack(&s, 3);SLPushBack(&s, 2);SLPushBack(&s, 1);SLprint(s);SLPushFront(&s, 3);SLPushFront(&s, 4);SLprint(s);SLPopBack(&s);SLprint(s);SLpopFront(&s);SLprint(s);SLDestory(&s);return 0;
}

没有一点容错, 学废了吗
在这里插入图片描述

3. 顺序表实现完整代码

Seqlist.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SeqDataType;typedef struct SeqList
{SeqDataType* arr;int size;int capacity;
}SL;void SLInit(SL* ps);
void SLDestory(SL* ps);void SLCheckCapacity(SL* ps);
void SLPushBack(SL* ps, SeqDataType x);
void SLPushFront(SL* ps, SeqDataType x);void SLprint(SL ps);void SLPopBack(SL* ps);
void SLpopFront(SL* ps);

Seqlist.c

#include"Seqlist.h"void SLInit(SL* ps)
{assert(ps);ps->arr = NULL;ps->size = ps->capacity = 0;
}void SLDestory(SL* ps)
{assert(ps);if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->capacity = ps->size = 0;
}void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){int Newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SeqDataType* tmp = (SeqDataType*)realloc(ps->arr, Newcapacity * sizeof(SeqDataType));if (tmp == NULL){perror("realloc fail");exit(1);}ps->arr = tmp;ps->capacity = Newcapacity;}
}//尾插
void SLPushBack(SL* ps, SeqDataType x)
{assert(ps);SLCheckCapacity(ps);ps->arr[ps->size++] = x;
}void SLPushFront(SL* ps, SeqDataType x)
{assert(ps);SLCheckCapacity(ps);for (int i = ps->size; i>0; i--){ps->arr[i] = ps->arr[i-1];//最后一次ps->arr[1] = ps->arr[0]}ps->arr[0] = x;ps->size++;
}void SLprint(SL ps)
{for (int i = 0; i < ps.size; i++){printf("%d ", ps.arr[i]);}printf("\n");
}void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);ps->size--;
}void SLpopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0; i <=ps->size-2 ; i++){ps->arr[i] = ps->arr[i + 1];//arr[size-2] = arr[size-1]}ps->size--;
}

test.c

#include "Seqlist.h"int main()
{SL s;SLInit(&s);SLPushBack(&s, 4);SLPushBack(&s, 3);SLPushBack(&s, 2);SLPushBack(&s, 1);SLprint(s);SLPushFront(&s, 3);SLPushFront(&s, 4);SLprint(s);SLPopBack(&s);SLprint(s);SLpopFront(&s);SLprint(s);SLDestory(&s);return 0;
}

4. 总结

顺序表是一种线性数据结构,用于存储具有相同数据类型的数据元素。它通过一片连续的存储空间来存储数据,可以按照元素的物理顺序来访问和操作。

在顺序表中,元素的存储位置是连续的,可以通过下标来访问元素。通过下标,可以快速访问和修改顺序表中的元素,这是顺序表的一个重要特点。

顺序表的插入操作比较复杂,需要将插入位置之后的所有元素后移一位,然后将新元素插入到空出的位置。删除操作也类似,需要将删除位置之后的所有元素前移一位,然后将最后一个元素删除。

顺序表的优点是存储和访问元素的效率高,可以随机访问元素。而缺点是插入和删除操作的效率相对较低,需要进行大量的数据迁移。

顺序表适用于元素数量固定且不经常变动的场景,例如存储静态的数据集合。在元素数量会经常变动的情况下,使用链表等动态数据结构更为合适。

总之,顺序表是一种经典的线性数据结构,具有高效的存储和访问性能。但在插入和删除操作上稍显不足,适用于元素数量固定且不经常变动的场景。


看完, 记得点个关注

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

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

相关文章

第二期书生浦语大模型训练营第四次笔记

大模型微调技术 大模型微调是一种通过在预训练模型的基础上&#xff0c;有针对性地微调部分参数以适应特定任务需求的方法。 微调预训练模型的方法 微调所有层&#xff1a;将预训练模型的所有层都参与微调&#xff0c;以适应新的任务。 微调顶层&#xff1a;只微调预训练模型…

oracle 12c+ max_string_size参数

一个客户的数据库版本是19.3,在做数据库复制的时候,目标端报错了,查看了一下问题发现表的字段长度有不对,在12c以前我们都知道varchar的长度最大是4000,但是客户这里居然有32767: 把客户的建表语句弄出来,放到我的一个19c的测试环境进行测试: 发现报错了: 这里报错很明显了,是M…

学习c语音的自我感受

因为是自学&#xff0c;所以走过不少弯路。去年&#xff0c;受知乎“python性能弱”风潮的影响&#xff0c;学过go,rust。 在学习这些新语言的时候&#xff0c;由衷感受到&#xff0c;或是本身侧重方向的原因&#xff08;如go侧重服务器&#xff09;&#xff0c;或是语言太新不…

uniapp——组件多颜色模块展示、气泡框

一、自定义颜色&#xff1a; 样式 代码 <template><view class"content"><!-- 右上角 --><view class"coverStatus" :class"[itemClass, positionClass,cornerClass,sanJiaoCss,sanJiaoCss2]":style"dynamicStyle&q…

python getsize如何使用

第一步&#xff0c;点击键盘 winr&#xff0c;打开运行窗口&#xff1b;在窗口中输入“cmd"&#xff0c;点击确定&#xff0c;打开windows命令行窗口。 第二步&#xff0c;在windows命令行窗口中&#xff0c;输入“python”&#xff0c;进入python交互窗口。 第三步&#…

笔记 | 嵌入式系统概论

1 嵌入式系统简介 1.1 嵌入式系统的定义 根据美国电气与电子工程师学会&#xff08;IEEE&#xff1a;Institute of Electrical and Electronics Engineers )的定义&#xff0c;嵌入式系统是用于控制、监视或辅助操作机器和设备的装置(原文: devices used to control, monitor…

WiFi、Ethenet、4G优先级切换

1、多网卡情况下如何调整优先级方案 按照目前公司前辈给出的方案&#xff0c;调整优先级的手段有两种&#xff1a; <1>.删除默认路由--route del 的方法 <2>.ifmetric源码提供的修改路由表的mteric的值来设置路由的优先级&#xff0c;metric越小优先级越高。 应…

ANSYS Help 的使用

ANSYS 帮助文档是相当实用且重要的第一手资料&#xff0c;90% 以上的纯操作问题都可以在帮助文档找到相关的解释。 点击开始菜单的 ANSYS Help即可打开帮助文档 帮助文档有两种打开方式&#xff1a; 基于帮助文档的安装包安装于本地后&#xff0c;可直接启动帮助程序没有安装…

Spring-IOC之组件扫描

版本 Spring Framework 6.0.9​ 1. 前言 通过自动扫描&#xff0c;Spring 会自动从扫描指定的包及其子包下的所有类&#xff0c;并根据类上的特定注解将该类装配到容器中&#xff0c;而无需在 XML 配置文件或 Java 配置类中逐一声明每一个 Bean。 支持的注解 Spring 支持一系…

书生·浦语大模型实战营之Llama 3 高效部署实践(LMDeploy 版)

书生浦语大模型实战营之Llama 3 高效部署实践&#xff08;LMDeploy 版&#xff09; 环境&#xff0c;模型准备LMDeploy chatTurmind和Transformer的速度对比LMDeploy模型量化(lite)LMDeploy服务(serve) 环境&#xff0c;模型准备 InternStudio 可以直接使用 studio-conda -t …

机器学习运用-民宿价格

项目简介 随着旅游业的蓬勃发展&#xff0c;民宿市场迎来了前所未有的增长机遇。正好最近在参加拓尔思数据挖掘公益实习活动&#xff0c;我的项目将应用机器学习技术开发一个价格预测模型。可以达到更好地理解和预测民宿价格的目的&#xff0c;该模型综合考虑了从容纳人数、便…

【Python】Python函数的黑魔法:递归,嵌套函数与装饰器

欢迎来到CILMY23的博客 本篇主题为&#xff1a; Python函数的黑魔法&#xff1a;递归&#xff0c;嵌套函数与装饰器 个人主页&#xff1a;CILMY23-CSDN博客 系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 感谢观看&#xff0c;支持的可以给个一键三连&#xff…

基于51单片机的矩阵按键扫描的proteus仿真

文章目录 一、按键按键按键消抖 二、独立按键仿真图仿真程序 三、矩阵按键仿真图仿真程序 四、总结 一、按键 按键 按键通常指的是电子设备上的一种输入装置&#xff0c;用于在按下时发送信号&#xff0c;以便设备执行相应的操作。按键可以分为独立按键和矩阵按键两种类型。 …

TRIZ理论下攀爬机器人的创新设计与研究

随着科技的飞速发展&#xff0c;机器人技术已广泛应用于各个领域。特别是在复杂环境下的作业&#xff0c;如灾难救援、太空探测等&#xff0c;对机器人的移动能力和适应性提出了更高要求。在这样的背景下&#xff0c;基于TRIZ理论的攀爬机器人设计与研究应运而生&#xff0c;它…

简单的图像处理算法

本笔记参考crazy_Bingo 基础&#xff1a; 图像处理都是用卷积矩阵对图像卷积计算&#xff0c;如3X3 的矩阵对640 X 480分辨率的图像卷积&#xff0c;最终会得到638 X 478 的图像。卷积过程是这样的&#xff1a; 一、中值滤波 &#xff1a; 找出矩阵中的最中间值作为像素点 中…

Flink的安装、项目创建、任务打包和部署完整实现,任务实现使用JAVA语言

Flink资源下载地址 Flink安装包下载地址 一、本地模式安装Flink 1、在Linux服务上&#xff0c;创建flink文件夹 mkdir flink 2、上传文件并解压 tar -zxvf flink-1.14.6-bin-scala_2.11.tgz 解压完成后&#xff0c;如图&#xff1a; 3、启动Flink 进入到解压目录下&#x…

YOLOv9训练损失、精度、mAP绘图功能 | 支持多结果对比,多结果绘在一个图片(消融实验、科研必备)

一、本文介绍 本文给大家带来的是YOLOv9系列的绘图功能&#xff0c;我将向大家介绍YOLO系列的绘图功能。我们在进行实验时&#xff0c;经常需要比较多个结果&#xff0c;针对这一问题&#xff0c;我写了点代码来解决这个问题&#xff0c;它可以根据训练结果绘制损失(loss)和mA…

Java的八大基本数据类型和 println 的介绍

前言 如果你有C语言的基础&#xff0c;这部分内容就会很简单&#xff0c;但是会有所不同~~ 这是我将要提到的八大基本数据类型&#xff1a; 注意&#xff0c;Java的数据类型是有符号的&#xff01;&#xff01;&#xff01;和C语言不同&#xff0c;Java不存在无符号的数据。 整…

Day:动态规划 LeedCode 123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV

123. 买卖股票的最佳时机 III 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之前的股票&a…

安全开发实战(2)---域名反查IP

目录 安全开发专栏 前言 域名与ip的关系 域名反查ip的作用 1.2.1 One 1.2.2 Two 1.2.3 批量监测 ​总结 安全开发专栏 安全开发实战http://t.csdnimg.cn/25N7H 这步是比较关键的一步,一般进行cdn监测后,获取到真实ip地址后,或是域名时,然后进行域名反查IP地址,进行进…