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

数据结构之旅(顺序表)

前言:  

         Hello,各位小伙伴们我们在过去的60天里学完了C语言基本语法,由于小编在准备数学竞赛,最近没有给大家更新,并且没有及时回复大家的私信,小编在这里和大家说一声对不起!,小编这几天会及时给大家更新初阶数据结构的内容,然后我们来学习今天的内容吧!

一. 顺序表的概念和结构

概念:顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。

结构:顺序表的底层结构式数组,对数组的封装,实现了常用的增删改查等接口。

二.顺序表分类

顺序表分为静态顺序表和动态顺序表:

1>静态顺序表:即数组大小是固定的

...
struct Seqlist
{int arr[1000];//定长数组int size;//有效数组个数
}SL;

2>动态顺序表:即数组大小不是固定的

...
struct Seqlist
{int *arr;int size;//有效数据的个数int capacity;//数组的容量
};

相比于静态顺序表,动态顺序表的优点:既不会因为空间内存不够而造成栈溢出,也不会因为数组容量很大而有效数字较少而造成空间的浪费!

三.动态顺序表的实现

动态顺序表的实现我们分为9个模块,初始化,尾插,头插,尾删,头删,顺序表的查找,插入指定位置的数据,删除指定位置的数据,顺序表的销毁!

在写代码之前我们创建3个文件:一个.h文件,两个.c文件其中的.h文件为seqlist.h用来包含顺序表的框架已经一些函数的声明,其中seqlist.c文件用来实现函数的定义test.c用来不断测试代码的正确性

在进行顺序表实现之前我们首先来对代码简化一下,因为后面要多次使用结构体变量,我们使用typedef来重定义一下.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
typedef int SLDatatype;
typedef struct SeqList
{SLDatatype* arr;int size;int capacity;
}SL;
//初始化
void SLInit(SL* ps);

1>顺序表的初始化

在.h文件中进行函数的声明,在seqlist.c中进行函数的定义

#include"seqlist.h"
void SLInit(SL* ps)
{ps->arr = NULL;ps->capacity = ps->size = 0;
}

同时小编在这里提醒大家一下在进行初始化的时候记得要进行结构体指针传递,否则只会改变形参而不会改变实参在这里小编给大家演示一下传递结构体值变量的时候:而如果传递的结构体的指变量则会同时改变实参和形参!我们在test.c文件中进行调试一下

我们看到此时实参和形参都发生了变化!

2>顺序表的尾插操作

顺序表的尾插操作大致分为两钟情况:空间足够与空间不够的情况

空间足够的情况下:

在空间足够的情况下,在有效数字的后面直接插入数字即可,可以发现有效数字的个数size做为下标的时候可直接进行插入!

空间不够的情况下:

在空间不够的情况下可以下size和capacity的值相等,要想进行数字的插入需要进行扩容操作!我们使用realloc函数来进行扩容。同时在扩容是要等倍扩容,这样会尽量减少空间的浪费!

void SLPushBack(SL* ps, SLDatatype x)
{assert(ps);//空间不够if (ps->capacity == ps->size){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDatatype* tmp = (SLDatatype*)realloc(ps->arr, newCapacity *sizeof(SLDatatype));if (tmp == NULL){perror("realloc!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空间足够ps->arr[ps->size++] = x;
}

 可以看出时间复杂度为O(1)。

同时我们在test.c文件中进行测试:

 3>顺序表的头插操作

我们在进行顺序表的头插操作时,需要先将原来数组的内容整体向后移动一位,然后再将要插入的数据插入到第一个位置中去。同时我们将判断空间大小是否充足代码包装成一个函数

void CheckCapacity(ps)这样就可以使代码简洁。

代码实现:

void SLPushFront(SL* ps, SLDatatype x)
{assert(ps);void CheckCapacity(ps);//判断是否有足够的空间for (int i = ps->size; i > 0; i++){ps->arr[i] = ps->arr[i - 1];}//向后面整体移动一位ps->arr[0] = x;++ps->size;
}

 可以看出时间复杂度为O(n)。

4>顺序表的尾删操作

进行尾删操作时,将有效数字的个数减一,同时在判断有效数字个数不能为0。

void SLPopBack(SL* ps)
{assert(ps&&ps->size);--ps->size;
}

5>顺序表的头删操作

在进行头删操作时,我们只需要将数组内容整体向前移动一位即可!但在移动时我们要注意要从前向后移动。

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

 6>顺序表的查找操作

我们遍历整个数组,找到后返回下标,如果没有找到则返回-1,然后在test.c文件中进行测试

int SLFind(SL* ps, SLDatatype x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1;
}

测试:

7>在指定位置插入数据

 在指定位置插入数据,我们需要先将该位置之后的数据向后移动一位同时还要判断是否空间足够,然后在该位置插入数据。

void SLInsert(SL* ps, int pos, SLDatatype x)
{                  assert(ps);assert(pos >= 0 && pos <= ps->size);//取等号的时候就是在进行头插与尾插CheckCapacity(ps);for (int i = ps->size;i>pos;i--){ps->arr[i] = ps->arr[i - 1];}++ps->size;ps->arr[pos] = x;
}

测试:

8>删除指定位置的数据

删除指定位置的数据,即将该位置之后的数据向前移动一位,最后不要忘记将有效数据的个数减一。

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

测试:

8>顺序表的销毁

我们在开辟新的空间的时候使用了malloc函数,在使用完成之后要记得将所开辟的空间还给操作系统。

void SLDestory(SL* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->capacity = ps->size = 0;
}

测试:

四.完成顺序表所需要注意的事项(总结)

在整体规划部分,动态顺序表的实现过程中我们创建了3个文件与平常不同的是多出来一个test.c测试文件,因为我们要完成许多函数的功能所以创建这个函数目的在于不断测试,在上面我们在书写代码的过程中不断进行函数的测试,同时我们将所有函数的声明都存在了头文件中,在函数定义的文件中我们只需要包含我们创建的这个头文件即可!

在函数实现部分,我们充分考虑到了函数传参问题,将所有可能的情况包含到了其中,尤其传递的指针为空的情况还有值传递于址传递问题。同时将重复的代码部分另外包装成一个新的函数,减少了代码行数。同时在搞不清逻辑关系的时候我们要记得画图!

ok,今天的内容就到这里啦,我们下期再见! 欢迎各位小伙伴在评论区留言。

相关文章:

数据结构之旅(顺序表)

前言: Hello,各位小伙伴们我们在过去的60天里学完了C语言基本语法,由于小编在准备数学竞赛,最近没有给大家更新,并且没有及时回复大家的私信,小编在这里和大家说一声对不起!,小编这几天会及时给大家更新初阶数据结构的内容,然后我们来学习今天的内容吧! 一. 顺序表的概念和结…...

掌握 C# 内存管理与垃圾回收机制

内存管理是每个开发者需要了解的关键部分&#xff0c;特别是在构建高性能应用时。在 C# 中&#xff0c;垃圾回收&#xff08;Garbage Collection, GC&#xff09; 机制自动管理内存分配和释放&#xff0c;大大简化了内存管理的复杂性。然而&#xff0c;理解值类型与引用类型的区…...

【JavaEE】——初始网络原理

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;局域网 1&#xff1a;概念 二&#xff1a;局域网的连接方式 1&#xff1a;网线直连 …...

Nginx和Lua配合使用

在NGINX中使用Lua进行开发时&#xff0c;可以通过不同的配置块来指定Lua脚本的执行位置。这些配置块被称为“phase hooks”&#xff0c;即阶段挂钩。每个阶段挂钩都有其特定的作用时间和目的。以下是NGINX Lua模块中常见的配置指令及其用途&#xff1a; 常见的Phase Hooks 1.a…...

程序化交易是什么,它有哪些优势,需要注意什么?

炒股自动化&#xff1a;申请官方API接口&#xff0c;散户也可以 python炒股自动化&#xff08;0&#xff09;&#xff0c;申请券商API接口 python炒股自动化&#xff08;1&#xff09;&#xff0c;量化交易接口区别 Python炒股自动化&#xff08;2&#xff09;&#xff1a;获取…...

水库抽样算法(大数据算法作业)

时隔一个多月&#xff0c;终于想起来写大数据算法基础的实验报告&#xff0c;主要是快截止了&#xff0c;hh 这两天加急把这个报告写完了~ 接下来&#xff0c;写一写证明过程&#xff08;参考书籍&#xff1a;高等教育出版社《数据科学与工程算法基础》&#xff09;主要代码以…...

SHCTF-2024-week1-wp

文章目录 SHCTF 2024 week1 wpMisc[Week1]真真假假?遮遮掩掩![Week1]拜师之旅①[Week1]Rasterizing Traffic[Week1]有WiFi干嘛不用呢&#xff1f; web[Week1] 单身十八年的手速[Week1] MD5 Master[Week1] ez_gittt[Week1] jvav[Week1] poppopop[Week1] 蛐蛐?蛐蛐! SHCTF 2024…...

docker-comapose安装部署mysql

docker-comapose安装部署mysql version: "3.4" services:mysql:image: docker.das-security.cn/middleware/mysql:8.4.1container_name: mysqlenvironment:- MYSQL_ROOT_PASSWORD密码volumes:- /etc/localtime:/etc/localtime- ./configs/mysql/initdb:/docker-entr…...

C语言初阶-数据类型和变量【下】

紧接上期------------------------->>>C语言初阶-数据类型和变量【上】 全局变量和局部变量在内存中存储在哪⾥呢&#xff1f; ⼀般我们在学习C/C语⾔的时候&#xff0c;我们会关注内存中的三个区域&#xff1a; 栈区 、 堆区 、 静态区 。 内存的分配情况 局部变量是…...

C++:命名空间(namespace)详细介绍与案例

命名空间&#xff08;namespace&#xff09;是C中的一个重要概念&#xff0c;用于组织代码和避免名称冲突。它们允许程序员将标识符&#xff08;如变量、函数、类等&#xff09;组织在一起&#xff0c;以便在较大的程序中防止命名冲突。 1. 基本概念 命名空间的基本定义方式如…...

专题十一_递归_回溯_剪枝_综合练习_算法专题详细总结

目录 1. 找出所有⼦集的异或总和再求和&#xff08;easy&#xff09; 解析&#xff1a; 方法一&#xff1a; 解法二&#xff1a; 总结&#xff1a; 2. 全排列 Ⅱ&#xff08;medium&#xff09; 解析&#xff1a; 解法一&#xff1a;只关心“不合法”的分支 解法二&…...

java中Runnable接口是什么?基本概念、工作原理、优点、`Runnable`与`Thread`的对比、与`Callable`接口的对比、实际场景

Runnable接口是Java提供的一种用于实现多线程的接口&#xff0c;通常用来定义任务的具体逻辑。与Thread类不同&#xff0c;Runnable接口只提供一种抽象方法run()&#xff0c;没有任何与线程的生命周期、管理相关的功能。它的主要作用是与Thread类或线程池&#xff08;如Executo…...

Mybatis Plus连接使用ClickHouse也如此简单

通过阅读列式数据库ClickHouse官网&#xff0c;不难看出它有支持JDBC规范的驱动jar包&#xff0c;可以直接集成到Object Relational Mapping框架等&#xff0c;下面我用SpringBootMybatisPlus环境连接ClickHouse来演示一下 集成步骤 1.Maven引入ClickHouse提供的JDBC依赖 <…...

什么社交平台可以找到搭子?分享多款找搭子必备的人气软件

在这个丰富多彩的世界里&#xff0c;我们常常渴望有一个志同道合的搭子&#xff0c;一起分享生活的点滴&#xff0c;共同探索未知的领域。无论是追寻美食的舌尖之旅&#xff0c;还是踏上充满惊喜的旅途&#xff1b;无论是在健身房挥洒汗水…… 找到一个合适的搭子&#xff0c;都…...

STM32 RTC实时时钟 F407 寄存器

RTC介绍 STM32F1: RTC模块拥有一组连续计数的计数器&#xff0c;在相应软件配置下&#xff0c;可提供时钟日历的功能。 即在F1系列&#xff0c;RTC的日历部分只有一个32位的寄存器 该寄存器直接存放 时间戳 的值&#xff0c;即&#xff1…...

矩阵等价、向量组等价、线性方程组同解与公共解的关系

矩阵等价 矩阵 A 、 B 等价 ⇔ 两矩阵秩相等 R ( A ) R ( B ) ⇔ 每个矩阵的行秩等于列秩&#xff0c;两个矩阵的行秩与列秩分别相等 ⇔ 若行满秩则列向量组等价 ⇔ 若列满秩则行向量组等价 \begin{align} 矩阵A、B等价\\ &\Leftrightarrow 两矩阵秩相等R(A)R(B)\\ &\…...

[Linux] Linux 进程程序替换

标题&#xff1a;[Linux] Linux 进程程序替换 个人主页水墨不写bug &#xff08;图片来源于网络&#xff09; 目录 O、前言 一、进程程序替换的直观现象&#xff08;什么是进程程序替换&#xff1f;&#xff09; 二、进程程序替换的原理 三、进程程序替换的函数&#xff08…...

【Linux系统编程】第三十一弹---深入理解静态库:从零开始制作与高效使用的完全指南

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、静态库 1.1、怎么做静态库 1.2、怎么使用静态库 1、静态库 1.1、怎么做静态库 在Linux环境下&#xff0c;通常使用GCC&am…...

FFmpeg 简介及其下载安装步骤

目录 一、FFmpeg 简介 二、FFmpeg 安装步骤 2.1 打开官网 2.2 选择FFmpeg系统版本 2.3 下载FFmpeg压缩包 2.4 将下载好的压缩包进行解压 2.5 设置环境变量 2.5.1 在搜索栏中搜索【环境变量】&#xff0c;然后单击将其打开 2.5.2 找到系统变量中的【Path】&#xff0c;点…...

使用CSS+SVG实现加载动画

使用CSSSVG实现加载动画 效果展示 CSS知识点 SVG元素使用SVG相关CSS属性运用 整体页面布局 <section><div class"box"><div class"loader"><svg><circle cx"40" cy"40" r"40"></circl…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...