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

栈与队列:设计循环队列

目录

题目🔥:

数据模型: 

本题大意: 

思路分析: 

代码分析:

一、定义队列

二、初始化、判断队列的空和满⭐

初始化:

空满的判断:

三、入队和出队🎇

入队:

出队:

总结:

四、获取队头元素和获取队尾元素

关于队尾:

五、销毁队列 

完整代码:


 

题目🔥:

  • 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
  • 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

  • MyCircularQueue(k): 构造器,设置队列长度为 k 。
  • Front: 从队首获取元素。如果队列为空,返回 -1 。
  • Rear: 获取队尾元素。如果队列为空,返回 -1 。
  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
  • isEmpty(): 检查循环队列是否为空。
  • isFull(): 检查循环队列是否已满。

数据模型: 

                                  

题源:622. 设计循环队列 - 力扣(LeetCode)

题目内容: 

本题大意: 

给予队列固定的长度值,当队列的长度等于固定的长度值后,任何的插入都无效,且队列进行出队后,并不会进行空间的释放(如果以链表形式创造),而出队后空下的空间会进行重复利用,以此达成循环要求。

思路分析: 

对于本题的队列,我们有两种创建方式,第一种是数组为底层进行创建,第二种是以链表的形式进行创建。

如果是链表的形式,我们可以采取单链表或则双向链表,因为链表循环的独特优越性,我们会在插入删除创建的问题上方便很多,但是当我们在获取队尾元素的时候,就会十分的复杂,因为需要遍历。

而如果选择数组为底层进行创建,那么重点就是循环的体现和队列的空满表现。

而对于本题,采取数组的方法较好一些。

代码分析:

一、定义队列

  • 因为,我们采取数组的方法解决问题,所以构建一个数组类型的结构体,也就是顺序表。
  • 同时因为是队列,我们需要队头、队尾、又因为因为选择数组,所以设计一个数组的空间指针,因为由限定长度,所以设计一个长度限定K。

二、初始化、判断队列的空和满⭐

初始化:

关于队列的初始化,需要考虑一些问题:

  • 队头和队尾指针,究竟代表的意思?
  • 如何判断队列的空和满?

第一个问题:

  • 因为本队列的底层是数组,所以back和 front 本质上是表示数组的下标,那么当我们进行初始化时,下标改如何定义?
  • 如果定义front ==0 back ==0 那么当我们入队时,back 是否改前进?这个问题和之前栈的栈顶和栈底关系一样  栈和队列:栈-CSDN博客
  • 所以,如果我们的初始化 back == 0那么back 表达的就是 队尾的后面一个位置的下标。

第二个问题:

  • 队列的空和满其实分为两种状态,如果是没有进入循环的状态下,当front == back  ==0时,可以表示队列是空的,即便back的意思是 队尾的后一个位置下标 
  • 但是当进入循环后,back == front == 0 后,其实可以表达队伍已经满了

                                     

  • 所以,对这种问题,我们可以采取两种方法,第一种是设置一个长度,当长度==0时表示空队列,当长度不等于空时则是满队列(仅限于在空满函数中进行)
  • 但是这种方法并不方便,于是我们设置了另一个方法,那就我们在初始化的时候可以多开一个位置
  • 也就说如果题目要求我们的开辟能够存储四个元素的队列是,我们开辟五个空间,且多出的这个空间是可以进行存储数据的,那么我们的判断条件发生了改变。

空满的判断:

obj->front == obj->back;
  • 如果队列是空,那么back == front 是恒成立的,在开辟了一个空间后,队列满了之后,队头指针的队尾指针二者始终差距一步,这是因为多开辟了空间之后,空间的长度始终大于队列的长度,以及队尾指针back 指向的是队尾后面一个位置 

(obj->back+1) % (obj->k+1) == obj->front;

  • 如何判断是否是满?这里分了两种情况,第一种没有进入循环,也就说队头位置没有变化,队尾指针指向了最后一个下标位置,在这种情况下,队列满了。
  • 第二种,在多次的插入和删除后,back指针在front指针前面一个位置,在这种情况下满了。
  • 而这两种情况下,都有一个共同点!长度!
  • 无论是进入循环前还是进入循环后,back指针所处在的位置(队尾后一个位置,数组是从0开始的)和空间的长度 进行 % 得出的结果如果和front 指针指向的位置一样,那么队列就满了!
  • 主要是利用了 % 操作符的特点, 一个数 a % 比它大的数 b  = 这个数本身 a 

三、入队和出队🎇

入队:

因为,back是指向队尾后一个位置,所以直接使用即可

但是因为题目要求插入成功为真,所以我们要进行判断,是不是队列满了于是我们就可以调用之前的判断是否满了的函数,且又因为会出现下图情况:

                               

所以还需要对back的指向进行调整。

出队:

删除其实只需要移动队头指针就行了,当然需要由元素存在,所以还得判断是否是空的!

同时也需要注意循环的问题:

                      

总结:

  • 其实插入和删除面对循环的调整都是利用了 % 和循环的特点,++都会时front 和back 变大,而进入循环后,% 空间的大小 后得到的数字就相当于进入了循环后所处在的位置。
  • 而如果++后front 和back 的数字都比空间大小 小,那么 % 后得到的数字还是他们本身,也就表示没有进入循环

四、获取队头元素和获取队尾元素

  • 队头直接获取即可,因为队头不论如何移动都只是获取队头指针指向的元素
  • 而获取队尾,则是要获取队尾指针指向的下标-1后的元素,所以关于队尾指针会有一些改动 

关于队尾:

在正常情况下获取队尾是这样的

但是不正常情况,也就说循环后,back指针指向的是数组的0下标位置,当这个back-1后就是越界了而且这时候的队尾元素其实就是队列数组下标为k的元素

所以,这里再次利用了 % 的特点:一个数 a % 比它大的数 b  = 这个数本身 a 

  • 所以如果我们进入了循环后或则进入循环前,这个back指针指向的下标是比空间长度小的,所以加上空间长度在%长度空间长度,得出的数字还是这个数
  • 而如果back指向的是0,而再进来了-1后,再加上空间长度,%之后得出的就是数组的最后位置的数字最后位置的下标

五、销毁队列 

完整代码:


相关文章:

  • ModuleNotFoundError: No module named ‘pycocotools‘
  • buildadmin+tp8表格操作(3)----表头上方按钮绑定事件处理,实现功能(选中或取消指定行)
  • Excel vlookup 如何使用
  • 【Linux】冯诺依曼体系结构、操作系统、进程概念、进程状态、环境变量、进程地址空间
  • 黑马程序员微服务 分布式搜索引擎3
  • 人机交互——自然语言生成
  • vue中绑定class样式和条件渲染
  • SmartSoftHelp 7.0 最专业的c#代码生成器
  • EMQX vs Mosquitto | MQTT Broker 对比
  • 振弦式渗压计的安装方式及注意要点
  • 英伟达AI布局的新动向:H200 GPU开启生成式AI的新纪元
  • 解决 uniapp 开发微信小程序 不能使用本地图片作为背景图 问题
  • 新生儿奶藓:原因、科普和注意事项
  • 软通动力赋能触觉智能打造嵌入式鸿蒙原生系统应用标杆
  • Linux系统下安装RabbitMQ超简单教程(非详细)(Centos8)
  • 5、React组件事件详解
  • HomeBrew常规使用教程
  • Javascript弹出层-初探
  • Linux gpio口使用方法
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • Swift 中的尾递归和蹦床
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 基于webpack 的 vue 多页架构
  • 记录:CentOS7.2配置LNMP环境记录
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 算法之不定期更新(一)(2018-04-12)
  • 探索 JS 中的模块化
  • 想使用 MongoDB ,你应该了解这8个方面!
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​configparser --- 配置文件解析器​
  • #AngularJS#$sce.trustAsResourceUrl
  • #图像处理
  • (C语言)共用体union的用法举例
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (Forward) Music Player: From UI Proposal to Code
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (搬运以学习)flask 上下文的实现
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (一一四)第九章编程练习
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转)母版页和相对路径
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • ***通过什么方式***网吧
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .NET Core 项目指定SDK版本
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @ConditionalOnProperty注解使用说明
  • @RunWith注解作用
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • [2016.7.Test1] T1 三进制异或
  • [30期] 我的学习方法