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

数据结构:设计循环队列


这道题让我们设计一个循环队列,队尾的下一个元素是队头,但不同的是,这个循环队列是固定大小的,队列满则无法插入元素。
我们有两种选择可以设计这个循环队列,一种是链表,一种是顺序表,我们比较一下再实现循环队列上的优劣来决定采用哪种选择。

选择哪种底层结构


在初始化的时候,链表要申请k个结点的空间,顺序表只需要申请k个元素的大小,从初始化来看,顺序表比链表简单。。

在入队的时候,链表插入一个数据,ptail就往后移,直到队列满,ptail就指向最后一个结点。

顺序表入队就入到rear所在的位置,rear后移一个,当队列满了的时候,rear=4,rear与k(k=4)取模就能回到原来的位置。

入队方面这两个差不多。

出队的时候,链表的phead只需要后移一个就可以了,顺序表的front也只需要后移一个就好了,也差不多。

从这些来看,顺序表比链表实现简单,所以我们在这使用顺序表来实现循环队列。

思路

在判断队列是否为空的时候,只需要判断front==rear是否成立就好了。

但我们发现,判断队列满的条件和判空条件一模一样:

所以我们选择多开一个空间,开k+1个长度的数组:
此时队列为满,rear=4,当(rear+1)%(k+1)==0时,队列就为满。
然后我们出队一个数据,再入队一个5:

此时队列里面的数据是:2 3 4 5,然后rear越界了,此时rear=5,我们只需要让rear%(k+1),就可以确保每次入队后rear没有越界了。

然后rear为0,(rear+1)%(k+1)front,也能判断出队列满了,说明我们这个判断队列是否满的条件没有问题。
我们此时再出队2 3 4 5,然后front就会一直后移,变成这样子:

我们发现front也会出现越界的情况,所以每次出队后都执行front%(k+1),防止front越界。

然后发现rear
front,又说明我们的队列判空条件也没有问题。
因为在函数中我们要用到大小k,所以多定义一个capacity用来表示容量。
综合以上分析,我们把思路理清楚了,可以来实现一下代码了。

使用顺序表实现循环队列

定义结构体

首先是定义结构体,我们需要一个指针接收数组首地址,队头front,队尾rear,容量capacity。

初始化

然后就是初始化这个队列的函数MyCircularQueue* myCircularQueueCreate(int k)
我们创建一个结构体类型的指针,然后申请结构体大小的空间,再用arr接收申请的k+1个大小的空间,让front=0,rear=0,capacity=k就好了。

判断队列是否为空和为满

我们先写判断队列是否为空的函数myCircularQueueIsEmpty(MyCircularQueue* obj)和是否为满的函数myCircularQueueIsFull(MyCircularQueue* obj)。
只需要判断表达式rear==front(是否为空)和表达式(rear+1)%(k+1)==front(是否为满)的结果就好了。

入队

然后就是入队操作,当队为满时则入队失败,返回false,反之插入元素,rear后移一位,然后rear和(k+1)取模(保证rear不越界)。

出队

然后是出队函数myCircularQueueDeQueue(MyCircularQueue* obj),出队需要判断队列是否为空,为空则返回false,不为空则执行出队操作,front++,然后front%(k+1)防止越界问题。

返回队头

接下来是队头函数myCircularQueueFront(MyCircularQueue* obj),如果队列是空返回-1,反之直接返回队头就好了。

返回队尾

然后是队尾函数myCircularQueueRear(MyCircularQueue* obj),如果队列为空,返回-1,不为空则返回rear前一个位置的元素,所以我们定义一个prev来代表队尾位置的元素。

但有一种特殊情况,当rear=0时,prev就等于-1了,所以当rear=0时,我们的prev应该等于k,这才是队尾元素。

代码如下:

销毁队列

最后就是销毁队列了,我们之前申请了什么空间就把什么空间释放掉,然后指针置为NULL,变量都置为0就好了。

http://www.cnnetsun.cn/news/3279385.html

相关文章:

  • YY0505-2012 医用无影灯辐射超标:从 30MHz 到 1GHz 的 6 项滤波整改方案
  • NumPy 2.0 二维数组索引与切片:5种高级用法与性能对比
  • CSAPP BombLab 逆向实战:6个Phase汇编代码逐行解析与GDB调试技巧
  • 基于 Playwright UI 自动化测试
  • ONNX模型C++高性能部署实战:从原理到10倍推理加速
  • PIC18F8722与DTH-08信号切换与上拉下拉配置详解
  • ADS131M02与MK64FX512VDC12的高精度工业测量方案
  • 如何快速掌握中兴光猫配置解密工具:面向开发者的完整指南
  • 微信公众号开发教程
  • Zynq PS 时钟子系统 3 种 PLL 功耗对比:Bypass 模式与动态关断策略
  • Unity AI寻路进阶:NavMeshModifier动态导航网格控制详解
  • AI智能体性能优化:内存管理与模型维护的工程实践
  • 企业微信机器人开发指南:文本消息发送功能实现
  • P8772 [蓝桥杯 2022 省 A] 求和题解前缀和思路
  • 插件化开发:Android端的插件化与ArkUI-X的结合(131)
  • MOSFET GS/G级电阻选型实战:3种应用场景下10K与100Ω阻值对比分析
  • OpenClaw本地AI调度中枢:Node.js版本适配与API路由实战指南
  • Unity URP全屏模糊插件:从Shader原理到工程实践
  • Coze扣子AI智能体开发实战:从零构建多Agent协同应用
  • QP/C++ 7.3.4构建失败:.pack文件缺失的深度解析与解决方案
  • mtr命令,看完这篇就够用!
  • FPGA程序固化实战:Quartus 23.1 转换JIC文件5步避坑指南(含Flash选型)
  • Text2SQL+LangGraph智能体
  • PN结测温电路设计:2N3904/2N3906三极管选型与LTC2991配置实战
  • 零壹教育:打破正则依赖!非结构化文本高效预处理方法总结
  • RTSP 与 RTP/RTCP 实战联调:5步搭建简易流媒体服务器与客户端
  • 用 OAS 光学软件仿真剪切干涉仪
  • OpenCV 4.8 与 ROS Noetic 相机标定实战:3步完成USB摄像头内参获取与验证
  • MIPI DSI 时钟与带宽计算:从800x600@60Hz到4K面板的3个关键公式与实例
  • 为什么是8时18分?皓贝一口腔医院开业时刻的深意