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

数据结构——循环队列

目录

循环队列的基本知识

循环队列的实现

定义

各个接口的实现


循环队列的基本知识

循环队列的定义

循环队列(Circular Queue)是一种使用固定大小的数组实现的队列,它将数组的首尾相连,形成环形,以充分利用空间并实现高效的入队(enqueue)和出队(dequeue)操作。

基本特点

  • 固定大小:循环队列通常有一个固定的大小,这意味着它能够存储的元素数量是有限的。
  • 循环利用空间:当队尾指针到达数组的末尾时,下一个元素会循环到数组的开头位置。
  • 高效操作:循环队列可以避免在数组末尾重新分配空间,从而提高入队和出队操作的效率。

基本操作

  1. 入队(Enqueue):在队尾添加一个元素。如果添加后队尾指针到达数组末尾,则循环回数组的开始位置。
  2. 出队(Dequeue):移除队首的元素。如果移除后队首指针到达数组末尾,则循环回数组的开始位置。
  3. 查看队首元素(Peek/Front):返回队首元素的值,但不移除它。
  4. 检查是否为空(IsEmpty):如果队首和队尾指针相同,且队列未满,则队列为空。
  5. 检查是否已满(IsFull):如果队尾指针在移动一位后将与队首指针相遇,或者队列的元素数量等于数组的大小,则队列为满。

适用场景

  • 当数据元素数量相对固定时,循环队列可以高效地利用内存空间。
  • 在需要频繁入队和出队操作的场景中,循环队列可以减少内存分配和回收的开销。

循环队列的实现

定义

循环队列的实现需要一个定长数组arr,一个头指针head,一个尾指针rear,还有用于记录数据个数的变量k。

​
typedef struct 
{int* arr;int head;int rear;int k;} MyCircularQueue;​

各个接口的实现

创造k个数据的循环队列

​
​
​
MyCircularQueue* myCircularQueueCreate(int k) 
{MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->arr = (int*)malloc(sizeof(int)*(k+1));obj->head = obj->rear = 0;obj->k = k;return obj;
}​​

这里为什么数据个数是k个,但开了k+1个空间?

首先,head指向队列的第一个元素,rear指向队列最后一个元素的下一个位置。

当rear == head的时候,队列可能是空,也可能是满;当队列满的时候,rear指向的应该是最后一个元素的下一个位置,也就是head(循环队列);当队列为空时,rear == head(rear和head可能不等于0)

所以判断队列为空和队列为满的条件是冲突的,所以特意开多一个空间,这样的话这个循环数组的任意时刻都有一个位置不存放元素,这两个判断条件也就不冲突了。

销毁循环队列

释放动态开辟的数组,把head、rear、k值0即可。

void myCircularQueueFree(MyCircularQueue* obj) 
{free(obj->arr);obj->head = obj->rear = obj->k = 0;
}

判断循环队列是否为空

判断rear和head是否相等就可以。

​
bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{return obj->head == obj->rear;
}​

判断循环队列是否为满

其实在创建数组的时候多开的那个空间就是专门为了rear准备的,这里队列为满时rear就不会和head指向同一位置,而是指向多开出来的那个空间。

理想情况下,rear + 1 == head就说明队列为满。

而如果rear刚好是数组的最后下标,rear+1就会越界,所以需要模上capacity(k + 1)。

bool myCircularQueueIsFull(MyCircularQueue* obj) 
{return (obj->rear + 1) % (obj->k + 1) == obj->head;
}

插入元素到队尾(入队列)

如果插入成功,返回true。

注意先判断队列是否为满,如果满,返回false。

还需注意rear是否会越界的问题

​
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{if(myCircularQueueIsFull(obj)){return false;}obj->arr[obj->tail++] = value;//记得让rear模上一个周期(k+1),以防越界obj->rear %= (obj->k + 1);return true;
}​

删除队头元素(出队列)

删除成功就返回true。

注意判断队列为空和head的越界问题即可。

bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{if(myCircularQueueIsEmpty(obj)){return false;}obj->head++;//防止head越界obj->head %= (obj->k + 1);return true;
}

获取队头元素

注意队列为空,为空就返回-1。

int myCircularQueueFront(MyCircularQueue* obj) 
{if(myCircularQueueIsEmpty(obj)){return -1;}return obj->arr[obj->head];
}

获取队尾元素

还是注意如果队列为空,为空就返回-1。

​
int myCircularQueueRear(MyCircularQueue* obj) 
{if(myCircularQueueIsEmpty(obj)){return -1;}return obj->arr[(obj->rear + obj->k) % (obj->k + 1)];
}​

这里不能直接return obj->arr[rear - 1],因为rear有可能是0,还是得对rear进行特殊处理。

(rear + k + 1 - 1)% (k + 1)就可以处理上面这种特殊情况。


拜拜,下期再见😏

摸鱼ing😴✨🎞

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C#高级:通过一个遍历实体的小案例去理解反射(基础版)
  • Python之字符串的创建、索引和分片
  • 深入理解 GO 语言并发
  • 双配置视觉 Transformer 在多模态中的突破 !
  • Linux服务器:Samba配置
  • Java - 正则表达式
  • Memecoin的火爆与AMM在Solana上的主导地位
  • 嵌入式八股-C++面试30题(20240814)
  • Hibernate Session在项目中的创建方式
  • Nginx+Tomcat 群集
  • python发送外部请求
  • element 动态设置el-table 高度
  • Unity脚本一键修改所有预制体
  • Spring之@ComponentScan注解
  • HTTP/1.1
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【RocksDB】TransactionDB源码分析
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • Bootstrap JS插件Alert源码分析
  • co模块的前端实现
  • Intervention/image 图片处理扩展包的安装和使用
  • java多线程
  • js操作时间(持续更新)
  • Redis的resp协议
  • spring + angular 实现导出excel
  • Swoft 源码剖析 - 代码自动更新机制
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 动态魔术使用DBMS_SQL
  • 欢迎参加第二届中国游戏开发者大会
  • 聊聊flink的BlobWriter
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 物联网链路协议
  • 移动端 h5开发相关内容总结(三)
  • 组复制官方翻译九、Group Replication Technical Details
  • # Maven错误Error executing Maven
  • # 数据结构
  • #Ubuntu(修改root信息)
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (12)目标检测_SSD基于pytorch搭建代码
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (bean配置类的注解开发)学习Spring的第十三天
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (二)springcloud实战之config配置中心
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (算法二)滑动窗口
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转载)深入super,看Python如何解决钻石继承难题
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)