循环队列(C语言版)
循环队列(C语言版)
- 1.简单介绍循环队列
- 2.使用何种结构来实现
- 3.基本结构
- 4.初始化
- 5.判空判满
- 6.向循环队列插入一个元素
- 7.从循环队列中删除一个元素
- 8.获取队头队尾元素
- 9.释放空间
- 10.完整代码
🌟🌟hello,各位读者大大们你们好呀🌟🌟
🚀🚀系列专栏:【C++的学习】
📝📝本篇内容:简单介绍循环队列;使用何种结构来实现;基本结构;初始化;判空判满;向循环队列插入一个元素;从循环队列中删除一个元素;获取队头队尾元素;释放空间;完整代码
⬆⬆⬆⬆上一篇:C++priority_queue模拟实现
💖💖作者简介:轩情吖,请多多指教(> •̀֊•́ ) ̖́-
1.简单介绍循环队列
循环队列本质上是也是一个队列,也是“先进先出”的特性,只不过循环队列有空间限制,而不是可以无限添加元素,同时从逻辑上看,它是一个首尾相连的一个环形。
在leetcode上有一道题,也是实现循环队列的,可以看一下☞设计循环队列
2.使用何种结构来实现
对于实现循环队列,有两种选择,一种是使用顺序表,一种是使用链表,但是哪种更好呢?
我们先来看一下leetcode上要求写的函数,需要实现判空判满还有获取队尾数据等,首先谈谈判空判满,见下图:
可以发现,当循环队列满或者空时,front和rear都指向同一个结点,这样我们就难以区分,因此需要增加一个节点,因为它是循环的,这个节点在front,rear的调整的过程中也会存储上数据,但是下图中是不存储数据的,因为整个链表中必须有一个空的节点来保证能够区分空和满
但是链表能否完成获取队尾的数据,我们的链表是单循环链表,无法找到前置节点,所以说对于链表实现循环队列会比较麻烦,不过也可以使用双向循环链表来实现。
我们这边还是主要考虑使用顺序表来实现,front和rear都是下标,顺序表简单来讲只需要通过rear-1即可获取到我们的队尾元素。
顺序表的判满和判空和链表一样,需要多开一个空间,其实也可以增加一个size来判断满和空
3.基本结构
typedef struct {int* arr;//指向开辟的空间int k;//有效空间个数int front;//队头int rear;//队尾} MyCircularQueue;
我们直接在leetcode上完成循环队列的实现
按照我们之间画的图以及理解的,我们先需要声明一个结构体来预想一个循环队列
4.初始化
MyCircularQueue* myCircularQueueCreate(int k)
{MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));//先在堆上创建一个结构体变量obj->arr=(int*)malloc(sizeof(int)*(k+1));//顺序表的开辟;k+1是为了能多一个空间来区别空和满obj->k=k;obj->front=obj->rear=0;//队头和队尾一开始都指向顺序表的头,此时为空return obj;
}
5.判空判满
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{if(obj->front==obj->rear)//只要队头队尾指向同一个位置,那么循环队列就为空{return true;}return false;
}bool myCircularQueueIsFull(MyCircularQueue* obj)
{//rear的下一个位置是front那么就为满,k+1是因为k是有效空间个数,但是空间是多一个的if((obj->rear+1)%(obj->k+1)==obj->front){return true;}return false;
}
对于叛空没什么问题,但是大家可能对判满有一个疑问,为什么需要%?
如果不进行%的话,rear+1就直接超出了我们的循环队列,rear+1是6,k+1是6,进行%,正好和front相等。并且在rear+1在小于6的情况下(不超过循环队列时),并不会受%的影响
6.向循环队列插入一个元素
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value){if(myCircularQueueIsFull(obj)){//满了就不能放元素了return false;}obj->arr[obj->rear++]=value;//直接在rear位置放入元素,同时位置向后+1obj->rear%=(obj->k+1);//保证不会越界,如果超过的最后一个位置,就需要回到第一个位置return true;
}
rear始终指向有效元素的下一个位置,每次直接插入即可,不过插入完后要对rear进行++
在不停地插入和删除中,rear和front都会发生改变,因此对于rear我们也要对它进行调整,保证它不会越界,一旦指向越界,回到开头。
7.从循环队列中删除一个元素
bool myCircularQueueDeQueue(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){//循环队列为空就无法删除return false;}obj->front++;//直接队头位置+1即可obj->front%=(obj->k+1);//保证不会越界return true;
}
和前面插入元素一样,要保证front不能越界
8.获取队头队尾元素
int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){//保证不为空return -1;}else{return obj->arr[obj->front];}
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){//保证不为空return -1;}else{return obj->arr[(obj->rear+obj->k)%(obj->k+1)];//这里还需要%k+1是为了保证在其他情况下(rear不为0时)也能正常使用}
}
获取队头元素没什么好说的,主要是获取队尾元素,因为rear是指向最后一个元素的下一个位置,当rear为0时就不能直接rear-1来获取
上图分析了如何找到原位置,但是还要注意这只是一种情况,还有其他比较正常的情况也要适用,因此代码中需要%(k+1)
如果觉得使用%太复杂,也可以使用下面的方式
int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){//保证不为空return -1;}else{
//return obj->arr[(obj->rear+obj->k)%(obj->k+1)];//这里还需要%k+1是为了保证在其他情况下(rear不为0时)也能正常使用return obj->arr[obj->rear==0?obj->k:obj->rear-1];}
}
obj->k是有效空间的个数,它作为下标正好指向最后一个空间;rear正常情况下只需要-1即可访问队尾元素
9.释放空间
void myCircularQueueFree(MyCircularQueue* obj)
{free(obj->arr);free(obj);
}
10.完整代码
这部分完整代码是leetcode答题区的,而不是能直接放在编译器中直接运行的
typedef struct {int* arr;//指向开辟的空间int k;//有效空间个数int front;//队头int rear;//队尾} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));//先在堆上创建一个结构体变量obj->arr=(int*)malloc(sizeof(int)*(k+1));//顺序表的开辟;k+1是为了能多一个空间来区别空和满obj->k=k;obj->front=obj->rear=0;//队头和队尾一开始都指向顺序表的头,此时为空return obj;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {if(obj->front==obj->rear)//只要队头队尾指向同一个位置,那么循环队列就为空{return true;}return false;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {//rear的下一个位置是front那么就为满,k+1是因为k是有效空间个数,但是空间是多一个的if((obj->rear+1)%(obj->k+1)==obj->front){return true;}return false;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj)){//满了就不能放元素了return false;}obj->arr[obj->rear++]=value;//直接在rear位置放入元素,同时位置向后+1obj->rear%=(obj->k+1);//保证不会越界,如果超过的最后一个位置,就需要回到第一个位置return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){//循环队列为空就无法删除return false;}obj->front++;//直接队头位置+1即可obj->front%=(obj->k+1);//保证不会越界return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){//保证不为空return -1;}else{return obj->arr[obj->front];}
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){//保证不为空return -1;}else{
//return obj->arr[(obj->rear+obj->k)%(obj->k+1)];//这里还需要%k+1是为了保证在其他情况下(rear不为0时)也能正常使用return obj->arr[obj->rear==0?obj->k:obj->rear-1];}
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->arr);free(obj);
}/*** Your MyCircularQueue struct will be instantiated and called as such:* MyCircularQueue* obj = myCircularQueueCreate(k);* bool param_1 = myCircularQueueEnQueue(obj, value);* bool param_2 = myCircularQueueDeQueue(obj);* int param_3 = myCircularQueueFront(obj);* int param_4 = myCircularQueueRear(obj);* bool param_5 = myCircularQueueIsEmpty(obj);* bool param_6 = myCircularQueueIsFull(obj);* myCircularQueueFree(obj);
*/
🌸🌸循环队列(C语言版)的知识大概就讲到这里啦,博主后续会继续更新更多C++的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪
相关文章:
循环队列(C语言版)
循环队列(C语言版) 1.简单介绍循环队列2.使用何种结构来实现3.基本结构4.初始化5.判空判满6.向循环队列插入一个元素7.从循环队列中删除一个元素8.获取队头队尾元素9.释放空间10.完整代码 🌟🌟hello,各位读者大大们你们好呀&#…...
考研408笔记之数据结构(五)——图
数据结构(五)——图 1. 图的基本概念 1.1 图的定义 1.2 有向图和无向图 在有向图中,使用圆括号表示一条边,圆括号里元素位置互换没有影响。 在无向图中,使用尖括号表示一条边,尖括号里元素位置互换则表示…...
没有公网IP实现seafile本地IP访问和虚拟局域网IP同时访问和上传文件
前言 Ubuntu 24.04 LTSDocker 安装 seafileOpenWrtTailscale Ubuntu 24.04 LTS 通过 docker desktop 安装 seafile 搭建个人网盘中,已经实现了本地局域网放问Ubuntu IP来访问Seafile,以及通过 Ubuntu 的 Tailscale IP 访问Seafile。但是,文…...
【Hadoop面试题2025】
文章目录 简单题故障及相应的处理方法中等难度高难度小文件小文件的产生小文件问题的影响小文件治理方案推荐方案 冷文件冷文件的产生冷文件问题的影响冷文件治理方案推荐方案 简单题 一、基础概念类 什么是Hadoop? 答案:Hadoop是一个开源的分布式计算框…...
2000-2010年各省第三产业就业人数数据
2000-2010年各省第三产业就业人数数据 1、时间:2000-2010年 2、来源:统计年鉴、各省年鉴 3、指标:行政区划代码、地区、年份、第三产业就业人员数(万人) 4、范围:31省 5、指标解释:第三产业…...
第十一讲 多线程
多线程是提升程序性能非常重要的一种方式,也是Java编程中的一项重要技术。在程序设计中,多线程就是指一个应用程序中有多条并发执行的线索,每条线索都被称作一个线程,它们会交替执行,彼此间可以进行通信。 1. 进程与线…...
VUE之路由Props、replace、编程式路由导航、重定向
目录 1、路由_props的配置 2、路由_replaces属性 3、编程式路由导航 4、路由重定向 1、路由_props的配置 1)第一种写法,将路由收到的所有params参数作为props传给路由组件 只能适用于params参数 // 创建一个路由器,并暴露出去// 第一步…...
windows安装ES
1. 下载ES 访问ES官网下载Download Elasticsearch | Elastic 2. 配置环境变量 ES_JAVA_HOME : D:\jdk-17.0.9 ES_HOME : D:\elasticsearch-8.17.1-windows-x86_64\elasticsearch-8.17.1 3. 添加一些ES的配置 <1>关闭ES安全认证 打开elasticsearch-8.17.1\config\e…...
论文速读|Multi-Modal Disordered Representation Learning Network for TBPS.AAAI24
论文地址:Multi-Modal Disordered Representation Learning Network for Description-Based Person Search 代码地址:未开源(2025.01.22) bib引用: inproceedings{yang2024multi,title{Multi-Modal Disordered Repres…...
小哆啦解题记:加油站的奇幻冒险
小哆啦解题记:加油站的奇幻冒险 小哆啦开始力扣每日一题的第十三天 https://leetcode.cn/problems/gas-station/description/ 在环形道路上,矗立着一串加油站,宛如等待挑战的谜题。这条路上的每个加油站都有一桶汽油,而开车到下一…...
【前端】CSS实战之音乐播放器
目录 播放器背景旋转音乐封面按钮进度条音量调节音乐信息按钮的效果JavaScript部分播放和暂停音乐切换音乐信息进度条 音量调节避免拖拽时的杂音音量调节条静音和解除静音 自动下一首实现一个小效果最终效果 播放器背景 <div class"play_box"></div>设置…...
Games104——渲染中光和材质的数学魔法
原文链接 渲染方程及挑战 挑战 对于任一给定方向如何获得radiance–阴影 对于光源和表面shading的积分运算(蒙特卡洛积分) 对于反射光多Bounce的无限递归计算 基础光照解决方案 Blinn-Phong模型: 简化阴影 最常见的处理方式就是Shadow M…...
impala增加字段,hsql查不到数据
impala增加字段,插入数据后直接查看文件有值,impala查询是有值的,但是hsq查出来就没有值! Parquet格式的表,在重命名表的列名,或新增列名后,查询重名的列数据时显示当前列所有值为NULL。 原因&a…...
SpringBoot项目中的异常处理
定义错误页面 SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个叫 BasicExceptionController 来处理/error 请求,然后跳转到…...
ComfyUI实现老照片修复——AI修复老照片(ComfyUI-ReActor / ReSwapper)尚待完善
AI修复老照片,试试吧,不一定好~~哈哈 2023年4月曾用过ComfyUI,当时就感慨这个工具和虚幻的蓝图很像,以后肯定是专业人玩的。 2024年我写代码去了,AI做图没太关注,没想到,现在ComfyUI真的变成了工…...
NLTK命名实体识别(NER)
命名实体识别(Named Entity Recognition, NER)是自然语言处理(NLP)中的一项核心技术,旨在从文本中识别出具有特定意义的实体,如人名、地名、组织名等。通过对文本的自动化处理,NER能够帮助计算机理解和组织大量的非结构化数据,为信息抽取、搜索引擎优化、数据分析等领域…...
【游戏设计原理】78 - 持续注意力
这个原理指出,人类的注意力通常只能维持7至10分钟,因此游戏设计需要根据这一规律进行优化。具体建议包括: 短时间段设计:将游戏体验分解成7到10分钟的任务或场景,以符合玩家的注意力节奏。引入新刺激:在注…...
Android设备:Linux远程lldb调试
更多内容:XiaoJ的知识星球 目录 一、环境准备1.1 安装llvm/NDK1.2 开启lldb-server服务1.3 lldb连接lldb-server 二、使用lldb调试Android native源码2.1 运行调试2.2 .lldbinit文件 下面介绍Android设备(Android手机为例),在Linu…...
多层 RNN原理以及实现
数学原理 多层 RNN 的核心思想是堆叠多个 RNN 层,每一层的输出作为下一层的输入,从而逐层提取更高层次的抽象特征。 1. 单层 RNN 的数学表示 首先,单层 RNN 的计算过程如下。对于一个时间步 t t t,单层 RNN 的隐藏状态 h t h_t…...
[Computer Vision]实验三:图像拼接
目录 一、实验内容 二、实验过程及结果 2.1 单应性变换 2.2 RANSAC算法 三、实验小结 一、实验内容 理解单应性变换中各种变换的原理(自由度),并实现图像平移、旋转、仿射变换等操作,输出对应的单应性矩阵。利用RANSAC算法优…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...
Go 并发编程基础:select 多路复用
select 是 Go 并发编程中非常强大的语法结构,它允许程序同时等待多个通道操作的完成,从而实现多路复用机制,是协程调度、超时控制、通道竞争等场景的核心工具。 一、什么是 select select 类似于 switch 语句,但它用于监听多个通…...
Three.js进阶之粒子系统(一)
一些特定模糊现象,经常使用粒子系统模拟,如火焰、爆炸等。Three.js提供了多种粒子系统,下面介绍粒子系统 一、Sprite粒子系统 使用场景:下雨、下雪、烟花 ce使用代码: var materialnew THRESS.SpriteMaterial();//…...

在leetcode上有一道题,也是实现循环队列的,可以看一下☞设计循环队列





rear始终指向有效元素的下一个位置,每次直接插入即可,不过插入完后要对rear进行++


