当前位置: 首页 > 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;为了进一步降低成…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

ui框架-文件列表展示

ui框架-文件列表展示 介绍 UI框架的文件列表展示组件&#xff0c;可以展示文件夹&#xff0c;支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项&#xff0c;适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...