当前位置: 首页 > news >正文

玩转顺序表——【数据结构】

在C语言学习中,我们经常会遇见增删查改等一系列操作,而这些操作全都与线性表关联,没有线性表将会对这些操作完成的十分艰难!那今天就让我们来了解一下顺序表如何增删查改!!!

目录

1.线性表

2.顺序表 

2.1概念及结构

3.对顺序表的实现 

3.1创建动态内容结构体

3.2内存销毁 

 3.3判断是否需要扩容

3.4尾插

3.5头插

3.6 尾删

3.7头删

 3.8 顺序表查找

3.9 顺序表在pos位置插入x

3.10 顺序表删除pos位置的值

顺序表的问题及思考


1.线性表

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

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储

 

2.顺序表 

2.1概念及结构

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

顺序表一般可以分为:

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

 确定的数组是不能改变的

2.动态顺序表:使用动态开辟的数组存储:

通过存放一个结构体指针,使用动态内存开辟malloc函数开辟空间 ,如果空间不够用可以使用realloc函数进行扩容!

3.对顺序表的实现 

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

3.1创建动态内容结构体

typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{SLDataType* array;  // 指向动态开辟的数组size_t size ;       // 有效数据个数size_t capicity ;   // 容量空间的大小
}SL;

array是动态内存开辟的数组指针,指向开辟的首元素地址。

size是记录存储有效内容的数据个数,方便统计。

capicity是记录容量大小,方便与size进行比较,用来判断是否需要扩容。

我们使用typedef将int重命名为SLDataType,将结构体命名为SL。

 3.2对结构体进行初始化

//第一种方法
void SeqListInit(SL* ps)
{ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 4);if (ps->a == NULL){perror("malloc");exit(-1);}ps->size = 0;ps->capacity = 4;
}
//第二种方法
void SeqListInit(SL s)
{s.a = NULL;s.size = 0;s.capacity = 0;
}

第二种方法是直接将结构体的内容传给函数,形参只是实参的一份临时拷贝,形参的改变不会影响实参!!!所以第二种方法是错误的!!! 

当我们使用第一种方法初始化时,我们就可以适当的开辟一点空间,如何使用malloc开辟空间在之前的博客中有所讲解http://t.csdn.cn/038La。如果开辟失败我们就直接退出程序exit(-1)。

3.2内存销毁 

在我们使用动态内存开辟后,一定要及时释放空间并置为NULL,否则会出现内存泄漏等大问题!

void SeqListDestroy(SL* ps)
{free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}

 3.3判断是否需要扩容

在顺序表的增删查改中,我们时不时需要判断存入的数据是否已满,需不需要扩容。所以我们为了方便使用此功能避免程序冗余,我们可以创建此函数用来判断开辟的内存是否需要扩容。

void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){SLDateType* p = (SLDateType*)realloc(ps->a, sizeof(ps->a) * 2);if (*p == NULL){perror(realloc);exit(-1);}ps->capacity *= 2;ps->a = p;}
}

传入结构体指针,判断size与capacity是否相等,如果相等我们就使用realloc函数进行扩容,我们创建新指针指向新创建的空间,开辟比原来大二倍的空间。如果开辟成功我们将更新capacity的值,开辟失败直接退出程序!!!

3.4尾插

void SeqListPushBack(SL* ps, SLDateType x)
{SLCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}

 先使用函数SLCheckCapacity进行判断是否需要进行扩容,在进行尾部插入即可。

3.5头插

将需要的数据在顺序表的头部进行插入,对于顺序表而言效率会非常低,但是我们也必须将其实现。 

void SeqListPushFront(SL* ps, SLDateType x)
{SLCheckCapacity(ps);for (int i = ps->size; i > 0; i--){ps->a[i] = ps->a[i-1];}ps->a[0] = x;ps->size++;
}

3.6 尾删

尾删非常的简单,我们只需要将数组往前移动一位,size--即可。我们不必担心数据问题,下次再次使用时只需要将内容覆盖即可。

void SeqListPopBack(SL* ps)
{assert(ps->size > 0);ps->size--;
}

但是在删除时我们得判断顺序表中内容是否为空,防止数组越界。我们使用assert断言函数进行判断即可。

3.7头删

头删与头插的效率都很低下,这也是顺序表的一个大缺点。基本原理与头插差不多,时间复杂度都为O(n),牵一发而动全身。

void SeqListPopFront(SL* ps)
{assert(ps->size > 0);for (int i = 0; i < ps->size-1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

删除时我们必须判断数组是否为空,防止越界。从前向后进行迭代前移进行覆盖,最后将size--即可。

 3.8 顺序表查找

为了让我们方便查找顺序表中每个内容的具体位置,然后插入想插入的数据。我们创建一个寻找下标的函数。

int SeqListFind(SL* ps, SLDateType x)
{assert(ps->size > 0);for (int i = 0; i < ps->size; i++){if (ps->a[i] == x)return i;}elsereturn -1;
}

我们使用暴力查找法,将数组遍历一遍,如果能找到则返回其下标,如果找不到则返回-1结束。 

3.9 顺序表在pos位置插入x

我们使用3.8中的函数,将需要插入位置找到,然后使用此函数将其插入到顺序表中。

void SeqListInsert(SL* ps, int pos, SLDateType x)
{assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->a[end + 1] = ps->a[end];--end;}ps->a[pos] = x;ps->size++;
}

中间插入,前面的数据不需要移动,在pos后的位置要向后移动。

3.10 顺序表删除pos位置的值

void SeqListErase(SL* ps, int pos)
{assert(ps->size > 0);for (int i = pos - 1; i < ps->size-1; i++){ps->a[i] = pos->a[i + 1];}ps->size--;
}

与插入原理相同,pos后的内容向前一位即可。

顺序表的问题及思考

问题:

1. 中间/头部的插入删除,时间复杂度为O(N)

2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。

3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到 200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

思考:如何解决以上问题呢?下面给出了链表的结构来看看。

我们可以使用链表解决以上问题,下一期我们将走进链表章节。

欲知后事如何,尽情期待下一期!!! 

相关文章:

玩转顺序表——【数据结构】

在C语言学习中&#xff0c;我们经常会遇见增删查改等一系列操作&#xff0c;而这些操作全都与线性表关联&#xff0c;没有线性表将会对这些操作完成的十分艰难&#xff01;那今天就让我们来了解一下顺序表如何增删查改&#xff01;&#xff01;&#xff01; 目录 1.线性表 2…...

SSE(Server-Sent Events,服务器推送事件)和sockets(套接字)通信区别

SSE&#xff08;Server-Sent Events&#xff0c;服务器推送事件&#xff09;和sockets&#xff08;套接字&#xff09;都是用于实现实时通信的技术&#xff0c;但它们具有不同的特点和应用场景。 SSE 的优点&#xff1a; 简单易用&#xff1a;SSE 是基于HTTP协议的一种实时通…...

【设计模式——学习笔记】23种设计模式——代理模式Proxy(原理讲解+应用场景介绍+案例介绍+Java代码实现)

介绍 基础介绍 代理模式为一个对象提供一个代理对象&#xff0c;以控制对这个对象的访问。即通过代理对象访问目标对象&#xff0c;这样做的好处是&#xff1a;可以在不修改目标对象代码的基础上&#xff0c;增强额外的功能操作&#xff0c;即扩展目标对象的功能被代理的对象…...

大学英语四新视野 课后习题+答案翻译 Unit1~Unit8

Unit 1 Text A: Words in use 2022年6月16日 20:57 1 As the gender barriers crumbled, the number of women working as lawyers, doctors, or bankers began to increase significantly from the mid-20th century. 随着性别障碍的消除&#xff0c;从20世纪中期开始&am…...

Java入门指南:Java语言优势及其特点

目录 1. Java语言简介及发展概述 2. Java语言的优势 2.1 可移植性 2.2 面向对象 2.3 安全性 2.4 大量类库 3. Java语言与C/C的区别 4. 初识Java程序入口之main方法 5. 注释、标识符、关键字 5.1 注释 5.2 标识符 5.3 关键字 1. Java语言简介及发展概述 Java是一种面…...

Jenkins 节点该如何管理?

Jenkins 拥有分布式构建(在 Jenkins 的配置中叫做节点)&#xff0c;分布式构建能够让同一套代码在不同的环境(如&#xff1a;Windows 和 Linux 系统)中编译、测试等 Jenkins 的任务可以分布在不同的节点上运行 节点上需要配置 Java 运行时环境&#xff0c;JDK 版本大于 1.5 节…...

hugging face下载数据集

开始直接执行这个&#xff0c;下载下来的图片打不开 git clone https://huggingface.co/datasets/diffusers/dog-example 解决办法&#xff1a; 安装git lfs 1. curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash 2. sudo apt…...

解决Django报错 : No module named ‘MySQLdb‘

Django的版本是2.0&#xff0c;Python的版本号是3.6.4 在models.py创建好了模型类之后使用命令&#xff1a;python manage.py makemigrations 进行迁移&#xff0c;但是突然报错&#xff1a;ImportError:No module named MySQLdb 查询了相关资料发现python2.x版本是支持mysql…...

【Docker】Docker的优势、与虚拟机技术的区别、三个重要概念和架构及工作原理详细讲解

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 作者简介&#xff1a; 辭七七&#xf…...

【论文笔记】RCM-Fusion: Radar-Camera Multi-Level Fusion for 3D Object Detection

原文链接&#xff1a;https://arxiv.org/abs/2307.10249 1. 引言 目前的一些雷达-相机融合3D目标检测方法进行实例级的融合&#xff0c;从相机图像生成3D提案&#xff0c;并与雷达点云相关联以修正提案。但这种方法没有在最初阶段使用雷达&#xff0c;依赖于相机3D检测器&…...

STM32-风速传感器(ADC)

目录 0 说明 1 传感器介绍 2 代码说明 2.1 ADC.c 2.2 adc.h 2.3 main.c 0 说明 本篇文章主要是说明怎么使用STM32单片机读取风速传感器采集到的数据&#xff0c;读取方式是ADC&#xff0c;并且附带着STM32所需要的全部代码&#xff0c;所使用的风速传感器如下图所示。 附&am…...

【conda】配置国内镜像源

【conda】配置国内镜像源 1、官方2、国内常用镜像3、配置查看当前conda配置设置搜索是显示通道地址 4、清除缓存5、恢复默认全部删除指定删除 1、官方 https://docs.conda.io/projects/conda/en/latest/configuration.html 2、国内常用镜像 https://developer.aliyun.com/mi…...

python森林生物量(蓄积量)数据处理到随机森林估算全流程

python森林生物量&#xff08;蓄积量&#xff09;估算全流程 一.哨兵2号获取/处理/提取数据1.1 影像处理与下载采用云概率影像去云采用6S模型对1C级产品进行大气校正geemap下载数据到本地NDVI 1.2 各种参数计算&#xff08;生物物理变量、植被指数等&#xff09;LAI&#xff1a…...

使用Freemarker模版导出xls文件使用excel打开提示文件损坏

本文是通过一步步的还原事件的发生并解决的一个过程记录&#xff0c;如果想知道如何解决的可以直接跳转文章末尾结论部分 提示一下&#xff0c;关注一下 Table 标签中的 ss:ExpandedRowCount 属性 解决的问题 在项目中使用freemarker的xml模板导出xls格式的Excel文件时&#xf…...

初识Linux

今天简单了解了关于操作系统的发展史&#xff0c;学习了在Linux中如何远程连接云服务器的指令&#xff0c;以及在Linux中创建多个用户的指令。 1. ssh root 服务器远程地址 作用是用来连接XShell与云服务器&#xff0c;输入该指令后会自动生成输入密码的窗口&#xff0c;如…...

python——案例六:清空列表用clear()方法实现

案例六&#xff1a;清空列表用clear()方法实现LIST[0,1,2,3,4,5] print(清空前&#xff1a;,LIST) LIST.clear() print(清空后&#xff1a;,LIST)...

测试|Selenium之WebDriver常见API使用

测试|Selenium之WebDriver常见API使用 文章目录 测试|Selenium之WebDriver常见API使用1.定位对象&#xff08;findElement&#xff09;css定位xpath定位css选择器语法&#xff1a;xpath语法:校验结果 2.操作对象鼠标点击对象在对象上模拟按键输入clear清除对象输入的文本内容su…...

手把手教你uniapp和小程序分包

分包目的在于提高小程序的体积&#xff0c;多一个包就多2M&#xff0c;最多20M 常规的分包&#xff1a; 小程序一打开首先加载主包&#xff0c;然后再加载分包 分包可以用主包内的资源&#xff0c;主包不可以使用分包的资源 分包A不可以使用分包B里面的内容 分包可以使用a…...

Java中的代理模式

Java中的代理模式 1. 静态代理2. JDK动态代理3. CGLib动态代理 1. 静态代理 接口 public interface ICeo {void meeting(String name) throws InterruptedException; }目标类 public class Ceo implements ICeo{public void meeting(String name) throws InterruptedExcepti…...

LeetCode每日一题——1331.数组序号转换

题目传送门 题目描述 给你一个整数数组 arr &#xff0c;请你将数组中的每个元素替换为它们排序后的序号。 序号代表了一个元素有多大。序号编号的规则如下&#xff1a; 序号从 1 开始编号。一个元素越大&#xff0c;那么序号越大。如果两个元素相等&#xff0c;那么它们的…...

别再只盯着RTK了!聊聊GNSS/INS组合导航里,紧耦合如何用1颗卫星‘吊住’你的定位

1颗卫星的逆袭&#xff1a;紧耦合技术如何在极端环境下守护你的定位精度 想象一下&#xff0c;你正驾驶一辆L4级自动驾驶汽车穿越曼哈顿的钢铁森林。高楼间的"城市峡谷"让GPS信号时断时续&#xff0c;传统导航系统已经开始报警——"卫星信号丢失"。但你的车…...

基于GPT-5.4的本科毕业论文智能写作实战指南:从实验数据到完稿的全流程教程

摘要&#xff1a; 对于已完成实验并手握参考文献的大四学生而言&#xff0c;将 months of experiments 转化为符合学术规范的毕业论文往往是最具挑战性的环节。本教程系统介绍如何利用GPT-5.4这一先进的大语言模型&#xff0c;通过科学的提示词工程&#xff08;Prompt Engineer…...

Keil MDK-ARM中map文件解析与内存管理

Keil MDK-ARM中map文件全面解析1. 项目概述在嵌入式系统开发过程中&#xff0c;内存管理是至关重要的环节。map文件作为编译链接过程中生成的中间文件&#xff0c;包含了程序内存布局的完整映射信息。对于使用Keil MDK-ARM开发环境的工程师而言&#xff0c;深入理解map文件的结…...

PX4 OFFBOARD模式实战:手把手教你用C++代码让无人机自主起飞(附心跳包避坑指南)

PX4 OFFBOARD模式深度实战&#xff1a;从心跳包机制到三维轨迹控制的完整实现 当你的无人机在OFFBOARD模式下突然失控坠落&#xff0c;或者莫名其妙地退出自主控制模式时&#xff0c;是否曾怀疑过自己的代码逻辑&#xff1f;这些问题往往源于对PX4底层通信机制理解不够深入。本…...

OpenClaw备份策略详解:百川2-13B模型自动化容灾方案

OpenClaw备份策略详解&#xff1a;百川2-13B模型自动化容灾方案 1. 为什么需要自动化备份策略 去年冬天我经历过一次惨痛的教训——硬盘突然损坏导致三个月积累的模型微调数据全部丢失。那次事件后&#xff0c;我开始系统性地研究如何为本地部署的百川2-13B模型构建自动化备份…...

别再猜了!用Roboguide的TCP Trace功能,一键可视化发那科机器人涂胶轨迹的真实速度

发那科机器人涂胶轨迹速度优化实战&#xff1a;Roboguide TCP Trace深度解析 在汽车制造领域&#xff0c;涂胶工艺的质量直接影响车身密封性和防腐性能。传统调试方式依赖现场试错&#xff0c;既耗时又影响生产。本文将揭秘如何利用Roboguide的TCP Trace功能&#xff0c;实现涂…...

如何快速配置DLSS优化工具:终极性能提升指南

如何快速配置DLSS优化工具&#xff1a;终极性能提升指南 【免费下载链接】DLSSTweaks Tweak DLL for NVIDIA DLSS, allows forcing DLAA on DLSS-supported titles, tweaking scaling ratios & DLSS 3.1 presets, and overriding DLSS versions without overwriting game f…...

推荐系统优化秘籍:如何用Metric Learning解决冷启动问题?

推荐系统优化秘籍&#xff1a;如何用Metric Learning解决冷启动问题&#xff1f; 在推荐系统领域&#xff0c;冷启动问题一直是困扰算法工程师和产品经理的核心挑战之一。新用户缺乏历史行为数据&#xff0c;新商品没有足够的曝光记录&#xff0c;传统协同过滤方法在这些场景下…...

Llama-3.2V-11B-cot一文详解:low_cpu_mem_usage对加载速度提升37%

Llama-3.2V-11B-cot一文详解&#xff1a;low_cpu_mem_usage对加载速度提升37% 1. 项目概述 Llama-3.2V-11B-cot是基于Meta Llama-3.2V-11B-cot多模态大模型开发的高性能视觉推理工具&#xff0c;专为双卡RTX 4090环境深度优化。该工具通过一系列技术创新&#xff0c;显著提升…...

铜钟音乐:专注纯净听歌体验的终极免费音乐平台指南

铜钟音乐&#xff1a;专注纯净听歌体验的终极免费音乐平台指南 【免费下载链接】tonzhon-music 铜钟 (Tonzhon.com): 免费听歌; 没有直播, 社交, 广告, 干扰; 简洁纯粹, 资源丰富, 体验独特&#xff01;(密码重置功能已回归) 项目地址: https://gitcode.com/GitHub_Trending/…...