顺序表(第二节)实现和解析
目录
1.顺序表中的头文件 (每一种函数方法)
2.关于typedef 的用法
3.初始化和销毁表
3.1初始化表
3.2销毁表
4.打印表
5.自动扩容表!!!(重点)
6.头部插入表和尾部插入表
6.1尾部插入表
6.2头部插入表
7.头部删除表和尾部删除表
7.1判断表是否为空
7.2尾部删除表
7.3头部删除表
8. 指定位置的插入和删除
8.1指定位置的插入
8.2指定位置的删除
大家有什么不懂的可以私信问我,我也是刚学会!!
1.顺序表中的头文件 (每一种函数方法)
#define INIT_CAPACITY 4
typedef int SLDataType;
// 动态顺序表 -- 按需申请
typedef struct SeqList
{SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量
}SL;
//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);
//头部插⼊删除 / 尾部插⼊删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
//指定位置之前插⼊/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
我的讲述方法是对这几行代码一一进行讲解,建议复制一份在VS中,边看博客边看头文件,不然真的看不懂。
2.关于typedef 的用法
1.typedef用来给类型重命名,这里为什么要把int 重命名改为SLDataType呢?
因为如果用int的话后续的代码如果要更改,那就得把全部的int 都更改,如果提前typedef了就可以直接改 上面的类型就好了
2.下面把struct SeqList 改为SL仅仅是因为前面那一串太长了,给他缩短一点,增加代码的可读性
3.初始化和销毁表
3.1初始化表
初始化表,用于初始化变量。变量的使用前都是要初始化的。
a的指针的意思是指向 要填充的变量
capacity的意思是目前开辟的内存的量,size表示现在被占用的内存的量
void SLInit(SL* ps)
{ps->a = NULL;ps->capacity = ps->size = 0;
}
3.2销毁表
判断ps->a的原因是,判断这个指针是不是为空,如果为空,会不执行任何操作直接返回。
然后再给ps a 置空,capacity和size 置为0;
void SLDestory(SL* ps)
{if (ps->a){free(ps->a);}ps->a = NULL;ps->capacity = ps->size = 0;
}
4.打印表
打印表很简单,就用for循环遍历 realloc开辟的空间就好了(在下一部分自动扩容表讲解)
注意打印结束后换行,避免下次打印连在一起。
ps->a[ i ] 的意思就和数组一样。用来表示每一块开辟空间里的存储的值。
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}
5.自动扩容表!!!(重点)
1. 首先扩容表的前提是,你的capacity(现在总共开辟的内存量)和size(已有数据的内存)这两个变量已经相等,说明这时候的内存已经不够了,需要添加。
2.所以判断语句是 ps capacity == ps size(这里不写箭头了)。
3.看到下面的int newcapacity 其实是用来判断 ps->capacity是否为0.如果为0则就直接等于4
不等于就等于 2 * ps->capacity, (0 ?4 :2*ps capacity就是判断是否为0,真就为前,假就为后)。
4.为什么要判断是否为0呢?因为如果为0,你下面开辟的代码 realloc开辟出来的空间还是0
5.之和在判断是否为NULL开辟失败的情况。
6.最后将开辟的空间 再次赋予 ps a。
7.ps capacity = newcapacity。
void SLCheckCapacity(SL* ps)
{if (ps->capacity == ps->size){/*if (ps->capacity == 0) 判断capacity的情况,和下面newcapacity意思相同{ps->capacity == 4;}else{ps->capacity == ps->capacity * 2;}*/int newCapacity = ps->capacity == 0 ? 4 : 2*ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newCapacity);if (tmp == NULL){perror("realloc失败\n");return;}ps->a = tmp;ps->capacity = newCapacity;}
}
6.头部插入表和尾部插入表
6.1尾部插入表
很简单,1.首先需要断言 ps 是否为空 NULL,因为为空指针,进行解引用的时候会变成野指针。所以要保证传进来的指针不为空。
2.给一个上面的自动扩容表的函数,用来判断空间是否足够。
3.如果足够 则将 ps size 这个空间的位置赋值为x 。(因为是数组,所以第一个数的下标是0.所以ps size 表示被占用的空间数量,比如说有三个空间被占用,ps size =3,而被占空间的下标是0 1 2,所以3这个空间是没数值的,直接赋值即可。)
4.记得每次插入表给一个size ++;
void SLPushBack(SL* ps,SLDataType x)
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}
6.2头部插入表
一样的先断言看看ps是否为空。
1.与尾部插入不同的点就是,在头部插入,怎么在头部插入呢?
可以用for循环从后往前遍历一遍,将每一个数值都往后移一个内存。
2.然后再将 0 下标位置的内存赋值为 x。
3.插入表一定要size++
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);for (int i = ps->size; i > 0; i--){ps->a[i] = ps->a[i - 1];}ps->a[0] = x;ps->size++;
}
7.头部删除表和尾部删除表
7.1判断表是否为空
为什么要进行多一步判断表为空?
可以想象如果一个表都为空了,那它还删除什么?那肯定报错啊
所以在进行删除表的时候要进行判断表的有无。
bool 表达式只有两个值 真就是为true 为1,假就是 false 为0.
所以return的值要是一个表达式,用来判断是否为真或假。
bool SLIsEmpty(SL* ps)
{assert(ps);return ps->size == 0;
}
7.2尾部删除表
超简单的删除尾表。
1.一样的判断ps是否为空
2.判断表是否为空
3.对于一个开辟的表的内存,如果size--就说明有数据的空间-1. 下次在插入表数据的时候,直接使用这个空间,这样就是类似一个抽象的删除,因为下次添加数据还是用的这块内存,所以你不用给这块空间的数据清空也可以使用。
可以想象一个二手汽车,前一个拥有人想把它卖了,这时候这车就是无主车,等下一个车主来了,直接把前一个车主的名字改为下一个车主的名字即可。
void SLPopBack(SL* ps)
{assert(ps);assert(!(SLIsEmpty(ps)));ps->size--;
}
(!SLIsEmpty( ps )) 这个表达式的意思就是 上面用bool函数判断 表中有没有数据,
如果表中没有数据 就返回了一个1 ,用!来取反 所以这里就是 如果为1则断言程序终止。
如果为0就说明 有数据 程序继续进行。
7.3头部删除表
1.首先还是判断ps是否为空,和表是否为空
2.用for循环遍历把后一个的值赋予前一个。
为什么是 i < ps size - 1.因为我们只要有数据的空间,如果是 ps size不减一 那就会把 有一个空着的数据传到 最后一个位置。这是不需要的,因为是删除表,最后一个位置要被放弃的。
3.删除表 要 ps size --
void SLPopFront(SL* ps)
{assert(ps);assert(!(SLIsEmpty(ps)));for (int i = 0; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}
8. 指定位置的插入和删除
8.1指定位置的插入
1.首先判断 ps 是否为空,判断 pos 是否超出表的范围。
2.因为是插入表所以要判断空间是否足够
3.用for循环 从后往前遍历 将前一个的数值赋值给后一个
为什么是 i = ps size -1,因为 ps size 的值 是表示 有数据的空间个数,而对于空间的下标来说,ps size 这个数字的空间下表指向的反而是下一个无数据的空间。我们看第一组的转换
ps a【i + 1】= ps a【i】如果把i 换了 就变成了ps a 【ps size】 = ps a 【ps size -1】。
这样就很好理解了,把下一个空数据的内存赋值为 最后一个内存的值。
pos -1,和上面类似,可以自己思考一下。(不懂可以私聊我,看到必回)
4.最后在pos 那个位置插入数据 x
5.插入表 ps size++
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);for (int i = ps->size - 1; i > pos - 1; i--){ps->a[i + 1] = ps->a[i];}ps->a[pos] = x;ps->size++;
}
8.2指定位置的删除
1.因为是删除首先判断 ps 是否为空 表是否为空,在判断 要查找的数字是否在表数据的范围内。
2.这个删除和上面类似,就是要把前一个数据的值改为下一个数据的值即可,从pos的位置开始,因为要把pos位置的值给占领了。
3.ps size--
void SLErase(SL* ps, int pos)
{assert(ps);assert(!SLIsEmpty(ps));assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}
大家有什么不懂的可以私信问我,我也是刚学会!!
相关文章:
顺序表(第二节)实现和解析
目录 1.顺序表中的头文件 (每一种函数方法) 2.关于typedef 的用法 3.初始化和销毁表 3.1初始化表 3.2销毁表 4.打印表 5.自动扩容表!!!(重点) 6.头部插入表和尾部插入表 6.1尾部插入表 …...
Hadoop3教程(二十一):MapReduce中的压缩
文章目录 (123)压缩概述在Map阶段启用在Reduce阶段启用 (124)压缩案例实操如何在Map输出端启用压缩如何在Reduce端启用压缩 参考文献 (123)压缩概述 压缩也是MR中比较重要的一环,其可以应用于M…...
04、RocketMQ -- 核心基础使用
目录 核心基础使用1、入门案例生产者消费者 2、消息发送方式方式1:同步消息方式2:异步消息方式3:一次性消息管控台使用过程中可能出现的问题 3、消息消费方式集群模式(默认)广播模式 4、顺序消息分析图:代码…...
mysql中date/datetime类型自动转go的时间类型time.Time
在DSN中需要加入parseTimetrue&&locLocal,或 charsetutf8mb4&locAsia%2FShanghai&parseTimetrue。 package main_testimport ("database/sql""fmt""testing""time"_ "github.com/go-sql-driver/mysq…...
MATLAB算法实战应用案例精讲-【图像处理】机器视觉(基础篇)
目录 前言 几个高频面试题目 如何选择合适的面扫相机 如何选择光学滤波器 知识储备...
LDAP协议工作原理
LDAP,全称Lightweight Directory Access Protocol,译为轻量目录访问协议,是一个在互联网中广泛使用的协议,主要用于实现网络中的信息查找和检索。在身份认证方面,LDAP起着重要的作用。 LDAP的工作原理主要包括以下几个…...
【Jetpack Compose】BOM是什么?
前言 本篇旨在帮助小伙伴们了解和使用Compose中BOM相关的知识,在Compose的开发过程中更加便捷、统一的管理相关依赖信息。 BOM基础知识 Compose推出的BOM为物料清单的意思,BOM全称为Bill Of Materials,Compose推出BOM的意义旨在通过指定的…...
多域名SSL数字证书是什么呢
多域名SSL数字证书是众多SSL数字证书中最灵活的一款SSL证书产品。一般一张SSL证书只能保护一个域名,即使能保护多个域名站点,证书保护的域名类型也有限制(通配符SSL数字证书)。多域名SSL数字证书既能用一张SSL证书保护多个域名网站,又不限制域…...
杭电oj--求奇数的乘积
Problem Description 给你n个整数,求他们中所有奇数的乘积。 Input 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你可以假设每组数据必定至少存…...
E053-web安全应用-Brute force暴力破解初级
课程分类: web安全应用 实验等级: 中级 任务场景: 【任务场景】 小王接到磐石公司的邀请,对该公司旗下的网站进行安全检测,经过一番检查发现该论坛的后台登录页面上可能存在万能密码漏洞,导致不知道账号密码也能登录后台&am…...
外汇天眼;VT Markets 赞助玛莎拉蒂MSG Racing电动方程式世界锦标赛
随着国际汽联电动方程式世界锦标赛第十赛季的到来,外汇经纪商 VT Markets 和玛莎拉蒂 MSG Racing 宣布了一项为期多年的全球合作。 外汇天眼温馨提醒:在做外汇交易之前,一定要审核清楚外汇平台的资质以及官网信息,以防上当受骗&am…...
使用vscode + vite + vue3+ element3 搭建vue3脚手架
技术栈 开发工具:VSCode 代码管理:Git 前端框架:Vue3 构建工具:Vite 路由:vue-router 状态管理:vuex AJAX:axios UI库:element-ui 3 数据模拟:mockjs css预处理…...
竞赛 深度学习+opencv+python实现车道线检测 - 自动驾驶
文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数:3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 &am…...
spring boot 下载resources下的静态文件为流格式
废话不多说,直接上代码 一、下载逻辑 public void downAppApk(HttpServletResponse response){ClassPathResource classPathResource new ClassPathResource("app/xxxxxx.apk");if (!classPathResource.exists()) {throw new BusinessException("安…...
HTML渲染过程
整个渲染过程: 将 URL 对应的各种资源,通过浏览器渲染引擎的解析,输出可视化的图像。 基本概念: HTML 解释器:解析html语言、将html文本翻译成dom树; CSS 解释器:解析css语言,给…...
[已解决]llegal target for variable annotation
llegal target for variable annotation 问题 变量注释的非法目标 思路 复制时编码错误,自己敲一遍后正常运行 #** 将垂直知识加入prompt,以使其准确回答 **# prompt_templates { # "recommand":"用户说:__INPUT__ …...
nodejs基于vue小型企业银行账目管理系统
这就产生了以台式计算机为核心的管理信息系统在大规模的事务处理和对工作流的管理等方面的应用,在银行帐目管理之中的应用日益增加 且会出现信息的重复传递问题,因此该过程需要进行信息化,以利用计算机进行帐目管理。 3.1 银行帐目管理系统功能模块 …...
pointnet和pointnet++点云分割和分类
目录 1. pointnet 1.1 点云数据的特点 1.2 模型功能 1.3 网络结构 1.3.1 分类网络 1.3.2 分割网络 2. pointnet 2.1 模型 2.2 sampling layer组件 2.3 grouping layer 2.4 pointnet 1. pointnet 1.1 点云数据的特点 (1)无序性:…...
Docker-compose和Consul
目录 1、docker-compose 简介 1.1 Docker-compose 简介 2、compose 部署 2.1 Docker Compose 环境安装 2.2 YAML 文件格式及编写注意事项 * * * * 2.3 Docker Compose配置常用字段 2.4 Docker Compose 常用命令 2.5 Docker Compose 文件结构 3、Consul 3.1 什么是…...
AFL模糊测试+GCOV覆盖率分析
安全之安全(security)博客目录导读 覆盖率分析汇总 目录 一、代码示例 二、afl-cov工具下载 三、编译带覆盖率的版本并启动afl-cov 四、AFL编译插桩并运行afl-fuzz 五、结果查看 AFL相关详见AFL安全漏洞挖掘 GCOV相关详见GCOV覆盖率分析 现将两者结合,即进…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
数据库正常,但后端收不到数据原因及解决
从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...
算法—栈系列
一:删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...
