循环队列(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算法优…...
除了ulimit -c unlimited:深入理解Linux core dump机制与高级配置指南
深入Linux核心转储:从基础配置到生产环境实战指南当服务器上的关键应用突然崩溃时,系统管理员最需要的就是一份完整的"事故现场记录"。Linux的core dump机制正是为此而生,它能保存程序崩溃时的内存状态、寄存器值和调用堆栈&#x…...
从‘文件夹’到对象列表:手把手教你用MinIO Java Client实现灵活的文件查询与过滤
从‘文件夹’到对象列表:手把手教你用MinIO Java Client实现灵活的文件查询与过滤在当今数据驱动的时代,对象存储已成为现代应用架构中不可或缺的一部分。MinIO作为高性能、兼容S3协议的开源对象存储解决方案,凭借其轻量级和易用性赢得了众多…...
top50 BF16算力(TFLOPS) 显卡排行榜 天梯图
排名显卡型号BF16算力(TFLOPS)售价(元)单TFLOPS价格(元)1B200(SXM)45002200000488.892H200(SXM)19801200000606.063MI300X1307750000573.834H100 SXM519501100000564.105RTX PRO 6000 Blackwell1150780000678.266H100 PCIe 80GB1560850000544.877RTX 50906803400050.008A100 80…...
告别网盘客户端!用Alist+RaiDrive把百度云盘变成电脑本地文件夹(保姆级图文教程)
用AlistRaiDrive实现网盘本地化管理的终极方案 你是否厌倦了电脑上安装多个网盘客户端,不仅占用系统资源,操作还繁琐割裂?每次上传下载文件都要在不同客户端间切换,效率低下。现在,通过Alist和RaiDrive的组合…...
告别鼠标手!5分钟上手开源鼠标连点器MouseClick,轻松实现自动化点击
告别鼠标手!5分钟上手开源鼠标连点器MouseClick,轻松实现自动化点击 【免费下载链接】MouseClick 🖱️ MouseClick 🖱️ 是一款功能强大的鼠标连点器和管理工具,采用 QT Widget 开发 ,具备跨平台兼容性 。软…...
搞定这 5 个全栈电商项目,面试别再用 Todo-List 凑数了
找独立开发练手项目或者写简历项目时,最忌讳两件事:一是太简单(纯前端 Mock 数据,点两下就没了),二是太假(一上来就硬套微服务、消息队列、高并发,结果自己根本Hold不住)…...
CANoe诊断测试没CDD文件怎么办?手把手教你用Fault Memory窗口和CAPL脚本读取解析DTC故障码
CANoe诊断测试无CDD文件的实战解决方案:从Fault Memory到CAPL脚本全解析当CDD文件缺失或定义不清晰时,诊断测试工程师常常陷入困境。本文将深入探讨如何利用Fault Memory窗口的基础功能,并通过CAPL脚本实现更灵活、更强大的故障码读取与解析方…...
别急着扔!12年老ThinkPad X230升级SSD和内存后,Win10流畅得像新电脑
12年老ThinkPad X230重生指南:极简升级打造流畅办公利器每次打开抽屉看到那台积灰的ThinkPad X230,总有种说不出的情感。这款2012年问世的经典商务本,曾陪伴无数人度过加班到凌晨的夜晚。如今性能确实有些力不从心,但直接丢弃又觉…...
从模糊到电影级景深:Midjourney + Topaz Gigapixel联调方案(含LUT预设包+PSD分层模板)
更多请点击: https://codechina.net 第一章:从模糊到电影级景深:Midjourney Topaz Gigapixel联调方案(含LUT预设包PSD分层模板) 当Midjourney生成的图像存在主体边缘柔化、背景层次缺失或分辨率不足等问题时…...
利用FTDI芯片MPSSE模式构建Arduino兼容开发环境
1. 项目概述:当FTDI芯片遇上Arduino生态如果你手头有一些闲置的FTDI USB转串口模块,比如常见的FT232R、FT2232H,或者像我一样,从某个旧设备上拆下来一块FT2232C的老古董,除了用来给单片机烧录程序或者做串口调试&#…...

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





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


