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

一篇博客读懂顺序表 —— Sequence-List

目录

一、顺序表的初始定义

1.1新建头文件和源文件

1.2 SeqList.h 中的准备工作

二、顺序表的初始化与销毁

三、首尾插入元素

四、首尾删除元素

五、中间插入元素

六、中间删除元素

 七、查找指定元素下标

八、源代码


一、顺序表的初始定义

1.1新建头文件和源文件

当我们要实现通讯录时,我们会自定义一个 contact.h 文件来存储我们的各种声明,自定义一个 contact.c 文件来存储实现声明的函数,同时还会存在一个 test.c 来测试我们代码的可行性。

在这里我们学习顺序表时,也要使用这种方式,来分割我们的代码使程序更加简洁耐看:

在 SeqList.h 中,我们要声明我们需要的头文件、重新定义的类型、我们需要的函数...... 

1.2 SeqList.h 中的准备工作

为了方便我们修改顺序表中的数据类型,我们把我们顺序表中的类型(int为例)重定义为SLDataType,这样如果我们以后想修改数据类型的话,可以直接来此处将 int 改为 double......

typedef int SLDataType;

 其次,我们定义的顺序表其实是一个结构体,其包含了一个表头(一个指针),实际保存的数据以及表的容量,这里我们并把结构体名称重定义为简称,方便后续的使用。

typedef struct SeqList
{int* p;//表头int size;//实际存储的数据数量int capacity;//此时表中的容量
}SL;

我们的顺序表要具有哪些特点呢?

1.动态存储,可以动态开辟使用空间

2.各种位置的增删查改,分为头、尾、中间。 

二、顺序表的初始化与销毁

初始化和销毁:

首先用断言来保证传入的指针不为空,其次我们需要用 SLInit 函数来将结构体中的数据一一赋初值,其次在销毁数据时,也要保证 free 函数的对象为非空指针,接着将数据重新初始化。

void SLInit(SL* psl) //初始化顺序表
{assert(psl != NULL);psl->p = NULL;psl->size = 0;psl->capacity = 0;
}
void SLDestroy(SL* psl) //销毁顺序表
{assert(psl != NULL);if (psl->p != NULL){free(psl->p);psl->size = 0;psl->capacity = 0;}
}

因为我们的顺序表是动态开辟空间,所以写一个检查实时容量的函数是必备的,在此处我们使用二倍扩容的方法来开辟内存空间,但是在初始化时我们把我们的 capacity 赋值为 0,在进行二倍扩容时还是 0,这时就可以用三目运算符完美规避这个问题。

检查并扩充容量:

并且我们用新的临时变量来保存扩容后的空间,在没有问题后再把值返回给原本的变量。

void SLCheckCapacity(SL* psl)
{assert(psl != NULL);if (psl->size == psl->capacity){//因为初始化时capacity为0,所以我们按照二倍扩容后也是0,这里运用三目运算符就能很好的解决SLDataType NewCapacity = (psl->capacity == 0) ? 4 : psl->capacity * 2;//动态开辟的空间是给顺序表的,注意不要把改行上下两个数据颠倒//sizeof() 不要忘!!SLDataType* tmp = (SLDataType*)realloc(psl->p, sizeof(SL) * NewCapacity);if (tmp == NULL){perror("SLCheckCapacity -> realloc");return;}psl->capacity = NewCapacity;psl->p = tmp;}
}

三、首尾插入元素

打印顺序表:

 为了更好的测试我们的代码,我们可以先写一个打印函数来打印我们的顺序表。

void SLPrint(SL* psl)
{assert(psl != NULL);int i = 0;for (; i < psl->size; i++){printf("%d ", psl->p[i]);}printf("\n");
}

尾部插入元素:

void SLPushBack(SL* psl, SLDataType x)
{assert(psl != NULL);SLCheckCapacity(psl);//检查是否需要扩容psl->p[psl->size] = x;psl->size++;
}

首部插入元素:

首部插入元素就比尾部插入元素复杂一点啦,我们需要让前面的元素覆盖后面的元素,下图我们模拟顺序表中有 8 个元素(size == 8),来看一下我们的代码应该如何写:

我们让 i 从后面开始向前走,才能保证有用的元素不会被覆盖,同时我们根据首尾元素的覆盖下标推理出 i 的取值范围。

//第一种取值
void SLPushFront(SL* psl, SLDataType x)
{assert(psl != NULL);SLCheckCapacity(psl);int i = psl->size;for (; i > 0; i--){psl->p[i] = psl->p[i - 1];}psl->p[0] = x;psl->size++;
}//第二种取值
void SLPushFront(SL* ps, SLDateType x)//ʱ临Ӷ O(n) ;  n O(n^2)
{assert(ps != NULL);SLCheckCapacity(ps);int i = ps->size - 1;for (; i >= 0; i--){ps->p[i + 1] = ps->p[i];}ps->p[0] = x;ps->size++;
}

四、首尾删除元素

尾部删除元素:

这里我们采用 size-- 的方法,让我们直接无法访问到最后一个元素,下一次增添时又会被新的元素覆盖以实现删除的操作,同时断言我们的实际元素个数必须多余 0

void SLPopBack(SL* psl)
{assert(psl != NULL);assert(psl->size > 0);psl->size--;
}

首部删除元素: 

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

五、中间插入元素

void SLInsert(SL* psl, int num, SLDataType x)
{assert(psl != NULL);assert(num >= 0 && num <= psl->size);SLCheckCapacity(psl);int i = psl->size - 1;for (; i >= num; i--){psl->p[i + 1] = psl->p[i];}psl->p[num] = x;psl->size++;
}

六、中间删除元素

void SLErase(SL* psl, int num)
{assert(psl != NULL);assert(num >= 0 && num < psl->size);SLCheckCapacity(psl);int i = num;for (; i < psl->size - 1; i++){psl->p[i] = psl->p[i + 1];}psl->size--;
}

 七、查找指定元素下标

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

八、源代码

欢迎光临我的Gitee - Gitee.comicon-default.png?t=N7T8https://gitee.com/bright-and-sparkling-at-night/studying/commit/dd1f9978f81f9decce01805623b4708b7671f3e0

相关文章:

一篇博客读懂顺序表 —— Sequence-List

目录 一、顺序表的初始定义 1.1新建头文件和源文件 1.2 SeqList.h 中的准备工作 二、顺序表的初始化与销毁 三、首尾插入元素 四、首尾删除元素 五、中间插入元素 六、中间删除元素 七、查找指定元素下标 八、源代码 一、顺序表的初始定义 1.1新建头文件和源文件 当我…...

OceanBase:02-单机部署(生产环境)

目录 一、部署规划 二、配置要求 三、部署前配置 1.配置 limits.conf 2.配置 sysctl.conf 3.关闭防火墙 4.关闭 SELinux 5.创建数据目录&#xff0c;修改文件所有者信息 6.设置无密码 SSH 登录 7.安装jdk 四、解压执行安装 五、OBD命令行部署 1.修改配置文件(all-c…...

【嵌入式 C 常用算法 2 -- 变量值交换函数异或方式实现】

文章目录 变量值交换函数异或方式实现 变量值交换函数异或方式实现 在C语言中&#xff0c;可以使用异或运算符&#xff08;^&#xff09;来进行两个数的交换&#xff0c;而不需要使用额外的临时变量。这种交换方式的基础是异或运算的以下性质&#xff1a; 任何数和 0 做异或运…...

Hadoop HDFS(分布式文件系统)

一、Hadoop HDFS(分布式文件系统) 为什么要分布式存储数据 假设一个文件有100tb&#xff0c;我们就把文件划分为多个部分&#xff0c;放入到多个服务器 靠数量取胜&#xff0c;多台服务器组合&#xff0c;才能Hold住 数据量太大&#xff0c;单机存储能力有上限&#xff0c;需要…...

力扣1.两数之和

原题链接&#xff1a;1.两数之和 根据题意可以得出 需要找出数组nums内 有两个元素相加等于target的两个整数&#xff0c;并且返回这两个证书的下标。并且数组内有重复元素&#xff0c;但是返回的答案不能有重复元素出现 要记住的就是&#xff0c;需要判断元素是否出现过&…...

JTA分布式事务管理器

XA协议:是一种标准协议&#xff0c;允许事务管理器协调多个资源管理器&#xff0c;确保在分布式事务中的一致性和原子性。 JTA:是JavaEE规范中的一种&#xff0c;用于管理分布式事务的 API&#xff0c;提供了事务的控制和协调机制 Atomikos理解成JTA的实现 XA是JTA的基础(JT…...

晨控CK-GW08系列网关控制器与CODESYS软件MODBUSTCP通讯手册

晨控CK-GW08系列是一款支持标准工业通讯协议ModbusTCP的网关控制器,方便用户集成到PLC等控制系统中。系统还集成了8路读写接口&#xff0c;用户可通过通信接口使用Modbus TCP协议对8路读写接口所连接的读卡器进行相对独立的读写操作。 晨控CK-GW08系列网关控制器适用于本公司多…...

读书笔记——labuladong算法笔记

读书笔记——labuladong算法笔记 序言计算机算法世界观计算机算法方法论二叉树遍历广度遍历BFS二叉树的前中后序遍历回溯算法动态规划算法二分搜索算法 其他算法滑动窗口双指针Union-Find算法 序言 labuladong算法笔记是一本讲解算法题求解技巧的书。本次读书笔记为2023年8月第…...

Linux中阶教程:bash shell基础

文章目录 输入输出赋值和计算条件判断函数for 循环数组及其遍历其他控制语句 输入输出 echo表示打印字符串&#xff1b;read表示获取用户输入&#xff1b;$用于引用变量。 # test1.sh bash中用#进行单行注释 echo "input your name:" read user_name echo "h…...

Golang 编译原理

简介 Golang&#xff08;Go语言&#xff09;是一种开源的编程语言&#xff0c;由Google开发并于2009年首次发布。它具备高效、可靠的特性&#xff0c;被广泛应用于云计算、分布式系统、网络服务等领域。Golang的编译原理是理解和掌握这门语言的重要基础之一。本文将介绍Golang…...

基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别 计算机竞赛

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…...

计算机视觉基础——基于yolov5-face算法的车牌检测

文章目录 车牌检测算法检测实现1.环境布置2.数据处理2.1 CCPD数据集介绍2.1.1 ccpd2019及20202.1.2 文件名字解析 2.2数据集处理2.2.1 CCPD数据处理2.2.2 CPRD数据集处理 2.3 检测算法2.3.1 数据配置car_plate.yaml2.3.2 模型配置2.3.3 train.py2.3.4 训练结果 2.4 部署2.4.1 p…...

【好书推荐】AI时代架构师修炼之道:ChatGPT让架构师插上翅膀

目录 前言 ChatGPT对架构师工作的帮助 快速理解和分析需求 提供代码建议和解决方案 辅助系统设计和优化 提高团队协作效率 如何使用ChatGPT提高架构师工作效率 了解用户需求和分析问题 编码实践和问题解决 系统设计和优化建议 团队协作和沟通效率提升 知识管理和文…...

全局代理和局部代理的区别

在计算机领域中&#xff0c;代理是一种常见的网络技术&#xff0c;它可以帮助用户更好地控制网络访问和数据传输。代理可以分为全局代理和局部代理两种&#xff0c;它们有着不同的作用和适用场景。 一、全局代理 全局代理指的是在系统级别设置的代理&#xff0c;它可以代理所…...

基于EPICS stream模块的直流电源的IOC控制程序实例

本实例程序实现了对优利德UDP6720系列直流电源的网络控制和访问&#xff0c;先在此介绍这个项目中使用的硬件&#xff1a; 1、UDP6721直流电源&#xff1a;受控设备 2、moxa串口服务器5150&#xff1a;将UDP6721直流电源设备串口连接转成网络连接 3、香橙派Zero3&#xff1a;运…...

Unity3D ECS架构适合作为主架构还是局部架构

前言 前言 Unity3D是一款广泛应用于游戏开发的跨平台游戏引擎&#xff0c;提供了丰富的功能和工具来简化游戏开发的过程。而Entity-Component-System&#xff08;ECS&#xff09;架构则是一种面向数据的设计模式&#xff0c;它将游戏对象&#xff08;Entity&#xff09;分解为…...

从零开始的目标检测和关键点检测(三):训练一个Glue的RTMPose模型

从零开始的目标检测和关键点检测&#xff08;三&#xff09;&#xff1a;训练一个Glue的RTMPose模型 一、重写config文件二、开始训练三、ncnn部署 从零开始的目标检测和关键点检测&#xff08;一&#xff09;&#xff1a;用labelme标注数据集 从零开始的目标检测和关键点检测…...

Qt6 中弹出消息框,一段时间后自动退出

以下代码功能&#xff0c;弹出模态消息框&#xff0c;然后&#xff0c;等待 3 秒&#xff0c;消息框自动退出 QMessageBox msgbox;msgbox.setText("sleep 3s");QTimer::singleShot(3000, &msgbox, &QMessageBox::close);msgbox.exec();...

elementUI树节点全选,反选,半选状态

// <template>部分 <div class"check-block"><el-divider></el-divider><el-checkbox :indeterminate"indeterminate" v-model"checkAll" change"handleCheckAllChange">全选</el-checkbox><e…...

Kafka、RabbitMQ、RocketMQ中间件的对比

消息中间件现在有不少&#xff0c;网上很多文章都对其做过对比&#xff0c;在这我对其做进一步总结与整理。 RocketMQ 淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件&#xff0c;使用Mysql作为消息存储媒介&#xff0c;可完全水平扩容&#xff0c;为了进一步降低成…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...