【Java数据结构】详解Stack与Queue(三)

🔒文章目录:

1.❤️❤️前言~🥳🎉🎉🎉

2. 队列(Queue)

2.1队列的概念 

2.2队列的方法 

2.3队列的使用 

2.4循环队列

循环队列的介绍

循环队列图

如何区分循环队列是满还是空 

数组下标循环技巧 

模拟实现循环队列

3.双端队列(Deque) 

4.总结


1.❤️❤️前言~🥳🎉🎉🎉

Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。

如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的内容感兴趣,记得关注我👀👀以便不错过每一篇精彩。

当然,如果在阅读中发现任何问题或疑问,我非常欢迎你在评论区留言指正🗨️🗨️。让我们共同努力,一起进步!

加油,一起CHIN UP!💪💪

🔗个人主页:E绵绵的博客
📚所属专栏:

1. JAVA知识点专栏

        深入探索JAVA的核心概念与技术细节

2.JAVA题目练习

        实战演练,巩固JAVA编程技能

3.c语言知识点专栏

        揭示c语言的底层逻辑与高级特性

4.c语言题目练习

        挑战自我,提升c语言编程能力

📘 持续更新中,敬请期待❤️❤️


借鉴文章:【Java---数据结构】队列-CSDN博客 

2. 队列(Queue)

2.1队列的概念 

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头 (Head/Front)

2.2队列的方法 


常用的方法为以上三个方法,但总共有六个方法。

🍓入队列:add()、offer()

相同:未超出容量,从队尾压入元素,返回压入的那个元素。
区别:在超出容量时,add()方法会对抛出异常,offer()返回false
🍓出队列:remove()、poll()

相同:容量大于0的时候,删除并返回队头被删除的那个元素。
区别:在容量为0的时候,remove()会抛出异常,poll()返回null
🍓获取队头元素(不删除):element()、peek()

相同:容量大于0的时候,都返回队头元素。但是不删除。
区别:容量为0的时候,element()会抛出异常,peek()返回null。

虽然有六个方法,但我们经常用的是 offer(),poll(),peek()。知道这另外三个方法就行了

此外我们还需记住size()和isEmpty(),这两个方法之前就见过,想必不用多说了。

2.3队列的使用 

由于队列是接口,所以我们不能实例化Queue,要用Queue去接收实现了Queue接口的实例化对象。

队列可以使用顺序表或链表的结构来实现:

当用链表结构来实现时,我们用LinkedList去实例化对象,再用Queue去接收。(LinkedList实现了Queue接口,上图有出现其关系)

当用顺序表结构来实现时,我们用ArrayDeque去实例化对象,再用Queue去接收。

(ArrayDeque实现了Queue接口)

 当用链表结构实现队列时,其使用代码如下:

public class Test1 {public static void main(String[] args) {Queue<Integer> queue=new LinkedList<>();queue.offer(4);queue.offer(3);queue.offer(2);queue.offer(1);System.out.println(queue.peek());queue.poll();queue.poll();System.out.println(queue);}
}


当用顺序表结构实现队列时,其使用代码如下: 

public class Test2 {public static void main(String[] args) {Queue<Integer> queue=new ArrayDeque<>();queue.offer(4);queue.offer(3);queue.offer(2);queue.offer(1);System.out.println(queue.peek());queue.poll();queue.poll();System.out.println(queue);}
}


注意:我们用println()打印Queue对象时能以字符串的形式打印出其内部的所有成员值。

2.4循环队列

循环队列的介绍

当我们使用顺序表实现队列时,会存在一个问题:虽然顺序表实现的队列可以自动扩容,但其空间利用不充分:因为每次出队都会浪费一个空间,为了解决这个问题,我们可以采用循环队列。
循环队列是一个特殊的队列:其底层还是数组,但不能实现自动扩容。入队时能够重新从数组的尾部跳到数组头部对已经出队的空间重新利用,这样就能够保证数组的每一个空间都可以被利用。

 循环队列图

如果将队列看做是一个循环,那么就可以看做是将数据存储在一个圆环里。


那现在有一个问题,当队列(数组)满的时候,font = rear ,而空的时候也是font=rear。那该怎么判断呢?

如何区分循环队列是满还是空 

1、定义一个变量size:记录队列元素个数。

每存放(入队)一个元素size++,每删除(出队)一个元素size--。
当size的值与顺序表的大小相等时,表示队列已满。
size值为0表示队列为空。

2、使用一个boolean类型的成员变量flag进行标记,初始值为false

每次入队时将flag的值置为true,出队将flag的值置为false,
当rear == front && flag == true表示队列已满。
当rear == front && flag == false表示队列为空。

3、浪费一个空间。

每次存放元素之前都先检查一下rear的下一个下标与 front 是否相等(也可以使用格式进行判断:(rear+1)% array.length 是否与 front 相等)
如果rear的下一个下标与 front 相等则表示队列已满。
如果rear == front则表示队列为空。

这样就导致其中必有一个空间存放不了值,相当于浪费了一个空间去使队列为空的标志和队列已满的标志有区别,从而使其能够判断出来。

数组下标循环技巧 

 同理在出队时,front 也会出现这种情况,所以使用方式:front = (front+1)%elem.length;

 模拟实现循环队列

📌题目描述:


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


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

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

📋题目示例 :

MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1);  // 返回 true
circularQueue.enQueue(2);  // 返回 true
circularQueue.enQueue(3);  // 返回 true
circularQueue.enQueue(4);  // 返回 false,队列已满
circularQueue.Rear();  // 返回 3
circularQueue.isFull();  // 返回 true
circularQueue.deQueue();  // 返回 true
circularQueue.enQueue(4);  // 返回 true
circularQueue.Rear();  // 返回 4

💥注意:

  代码示例:

class MyCircularQueue {Integer[] elements;int font;int rear;public MyCircularQueue(int k) {elements =new Integer[k+1];}public boolean enQueue(int value) {if(isFull())return false;else {elements[rear] = value;rear = (rear + 1) % elements.length;return true;}}public boolean deQueue() {if(isEmpty())return false;else{elements[font]=null;font=(font+1)%elements.length;return true;}}public int Front() {if (isEmpty())return -1;elsereturn elements[font];}public int Rear() {if(isEmpty())return -1;else{if(rear==0)return elements[elements.length-1];return elements[rear-1];}}public boolean isEmpty() {if(rear==font)return true;elsereturn false;}public boolean isFull() {if((rear+1)%elements.length==font)return true;elsereturn false;}
}

该题链接:循环队列的模拟实现

3.双端队列(Deque) 

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。

将队列的两端分别称为前端和后端,两端都可以入队和出队。所以双端队列既能够当队列使用,也能当栈使用。(重点这句话)

Java底层是使用LinkedList或ArrayDeque来实现双端队列(Deque)的,前面讲过,队列(Queue)也是使用LinkedList或ArrayDeque来实现的。(使用LinkedList是用链式结构去实现双端队列,使用ArrayDeque是用顺序结构去实现双端队列)

对于Deque的方法,我们常见的依旧是offerFirst,offerLast,pollFirst,pollLast,peekFirst,peekLast。其他的六个方法知道就行。 

除此之外我们也还需记住size()和isEmpty()。


 当用链表结构实现双端队列时,其使用代码如下:

public class Test3 {public static void main(String[] args) {Deque<Integer> deque= new  LinkedList<>();deque.offerLast(4);deque.offerFirst(3);deque.offerFirst(5);deque.offerLast(6);System.out.println(deque.peekLast());//6System.out.println(deque.peekFirst());//5deque.pollLast();deque.pollFirst();System.out.println(deque.peekLast());//4System.out.println(deque.peekFirst());//3}
}


 当用顺序表结构实现双端队列时,其使用代码如下:

public class Test4 {public static void main(String[] args) {Deque<Integer> deque= new ArrayDeque<>();deque.offerLast(4);deque.offerFirst(3);deque.offerFirst(5);deque.offerLast(6);System.out.println(deque.peekLast());//6System.out.println(deque.peekFirst());//5deque.pollLast();deque.pollFirst();System.out.println(deque.peekLast());//4System.out.println(deque.peekFirst());//3
}
}

4.总结

所以这篇文章我们就把队列的概念讲完了,下篇文章将带来队列和栈的习题练习。在此,我们诚挚地邀请各位大佬们为我们点赞、关注,并在评论区留下您宝贵的意见与建议。让我们共同学习,共同进步,为知识的海洋增添更多宝贵的财富!🎉🎉🎉❤️❤️💕💕🥳👏👏👏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/24325.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外挂知识库的基本知识与内容

外挂知识库 1.什么是rag&#xff1f; RAG,即LLM在回答问题或生成文本时&#xff0c;会先从大量文档中检索出相关的信息&#xff0c;然后基于这些信息生成回答或文本&#xff0c;从而提高预测质量。 2.外挂知识库的实现思路 只用几十万量级的数据对大模型进行微调并不能很好…

第五十六周:文献阅读

目录 摘要 Abstract 文献阅读&#xff1a;应用于地表水总磷浓度预测的可解释CEEMDAN-FE-LSTM-Transformer混合模型 一、现有问题 二、提出方法 三、方法论 1、CEEMDAN&#xff08;带自适应噪声的完全包络经验模式分解&#xff09; 2、FE&#xff08;模糊熵 &#xff09…

Vue3【十】07使用ref创建基本类型的响应式数据以及ref和reactive区别

Vue3【十】07使用ref创建基本类型的响应式数据以及ref和reactive区别 ref 也可以创建对象类型的响应式数据&#xff0c;不过要使用.value ref 处理对象数据的时候&#xff0c;底层数据还是reactive格式的 reactive 重新分配一个新对象&#xff0c;会失去响应式可以使用Object.a…

保姆级 | MySQL的安装配置教程(非常详细)

一、下载Mysql 官网步骤 MySQLhttps://www.mysql.com/进入官网首页 点击DOWNLOADS 点击MySQL Community (GPL) Downloads 点击 小页面直接进入 MySQL :: Download MySQL Installerhttps://dev.mysql.com/downloads/installer/点击“Download”下载最新版本&#xff0c;其他…

【吊打面试官系列】MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别?

大家好&#xff0c;我是锋哥。今天分享关于 【MySQL 中 InnoDB 支持的四种事务隔离级别名称&#xff0c;以及逐级之间的区别&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; MySQL 中 InnoDB 支持的四种事务隔离级别名称&#xff0c;以及逐级之间的区别&#xf…

碳素钢化学成分分析 螺纹钢材质鉴定 钢材维氏硬度检测

碳素钢的品种主要有圆钢、扁钢、方钢等。经冷、热加工后钢材的表面不得有裂缝、结疤、夹杂、折叠和发纹等缺陷。尺寸和允许公差必须符合相应品种国家标准的要求。 具体分类、按化学成分分类 &#xff1a; 碳素钢按化学成分&#xff08;即以含碳量&#xff09;可分为低碳钢、中…

机器学习笔记 - stable diffusion web-ui安装教程

一、Stable Diffusion WEB UI 屌丝劲发作了,所以本地调试了Stable Diffusion之后,就去看了一下Stable Diffusion WEB UI,网络上各种打包套件什么的好像很火。国内的也就这个层次了,老外搞创新,国内跟着屁股后面搞搞应用层,就叫大神了。 不扯闲篇了,我们这里从git源码直接…

问题:11单位内部人员对行政机关作出的行政处分不服,可申请行政复议. #其他#微信

问题&#xff1a;11单位内部人员对行政机关作出的行政处分不服,可申请行政复议. 参考答案如图所示

问题:脾梗塞时,下列情况最符合的是 #职场发展#知识分享#媒体

问题&#xff1a;脾梗塞时,下列情况最符合的是 A、脾肿大 B、脾区摩擦感 C、两者均有 D、两者均无 参考答案如图所示

uniapp视频组件层级太高,解决方法使用subNvue原生子体窗口

目录 前言 先看一下uniapp官网的原话&#xff1a; subNvue的一些参数介绍 subNvues使用方法&#xff1a; 绑定id 显示 subNvue 弹出层 subNvue.show() 参数信息 subNvue.hide() 参数信息 在使用subNvue 原生子体窗口 遇到的一些问题 前言 nvue 兼容性 以及使用方式 控…

把ROS程序作为桌面图标双击启动

1 写launch文件 把ROS程序写成一个launch文件&#xff0c;例如 powerline_with_rviz.launch <launch><!-- Load camera parameters --><rosparam file"$(find choose_powerline)/config/camera_params.yaml" command"load"/><!-- …

深入理解并应用KTT求解约束性极值问题

KT 很简单&#xff0c;口诀记心端&#xff0c;等式求最优&#xff0c;不等式验证——小飞打油 以后每期尝试编一句口诀&#xff0c;帮助大家记忆&#xff0c;可以是打油诗&#xff0c;也可以是类似“奇变偶不变&#xff0c;符号看象限”的口诀&#xff0c;如果编的不好&#xf…

Docker 常用命令以及镜像选择

目录 1.Docker基本组成 2.镜像选择 2.1、镜像推荐选择方案 2.2版本选择 3.Docker 命令 3.1镜像管理 拉取镜像&#xff1a; 列出镜像&#xff1a; 删除镜像&#xff1a; 构建镜像&#xff1a; 3.2容器管理 运行容器 列出运行中的容器和所有容器 停止容器 启动重启…

为什么要将Modbus转成MQTT

什么是Modbus Modbus 是一种串行通信协议&#xff0c;最初由Modicon&#xff08;现在的施耐德电气Schneider Electric&#xff09;于1979年开发&#xff0c;用于可编程逻辑控制器&#xff08;PLC&#xff09;之间的通信。Modbus协议设计简单&#xff0c;易于部署和维护&#xf…

从零入手人工智能(2)——搭建开发环境

1.前言 作为一名单片机工程师&#xff0c;想要转型到人工智能开发领域的道路确实充满了挑战与未知。记得当我刚开始这段旅程时&#xff0c;心中充满了迷茫和困惑。面对全新的领域&#xff0c;我既不清楚如何入手&#xff0c;也不知道能用人工智能干什么。正是这些迷茫和困惑&a…

M1Pro 使用跳板机

Mac (M1 Pro) 通过Iterm2 使用跳板机 1、由于堡垒机&#xff08;跳板机&#xff09;不能支持mac系统终端工具&#xff0c;只支持xshell等win生态。所以我们需要先安装iterm2 装iterms教程 这里头对rz、sz的配置不详细。我们可以这样配置&#xff1a; where iterm2-send-zmod…

Windows 11中删除分区的几种方法,总有一种适合你

序言 想从Windows 11 PC中删除一个分区,以便将空间重新分配给现有分区或创建一个新分区吗?我们将为你介绍删除Windows 11分区的多种方法。 删除Windows上的分区时会发生什么 删除分区时,Windows会擦除该分区的内容,并将该分区从电脑上的任何位置删除。你将丢失保存在该分…

单元测试覆盖率

什么是单元测试覆盖率 关于其定义&#xff0c;先来看一下维基百科上的一段描述&#xff1a; 代码覆盖&#xff08;Code coverage&#xff09;是软件测试中的一种度量&#xff0c;描述程序中源代码被测试的比例和程度&#xff0c;所得比例称为代码覆盖率。 简单来理解&#xff…

C语言实现map数据结构 key—value对应

1.首先43行 createKeyValuePair(char*key ,int value)这个函数就是给一个keyValuePair *pair的指针来通过内存分配将数据key和value存入这个pair指针所对应的内存空间 2.52行freeKeyValuePair这个函数是释放内存空间 3.头文件 struct结构体KeyValuePair就是一个指针一个值 4…

GO语言 服务发现概述

https://zhuanlan.zhihu.com/p/32027014 明明白白的聊一下什么是服务发现-CSDN博客 一、服务发现 是什么 在传统的系统部署中&#xff0c;服务运行在一个固定的已知的 IP 和端口上&#xff0c;如果一个服务需要调用另外一个服务&#xff0c;可以通过地址直接调用。 但是&…