【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…

自注意力机学习

自注意力机制的核心概念 1. Query, Key 和 Value Query&#xff08;查询向量&#xff09;&#xff1a;可以看作是你当前在关注的输入项。假设你正在阅读一段文字&#xff0c;这就像你当前在读的句子。 Key&#xff08;键向量&#xff09;&#xff1a;表示其他所有输入项的标识…

保姆级 | 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 兼容性 以及使用方式 控…

基于 中间件 的 数据交换平台 的实现

一、介绍 A. 背景和目的 随着云计算、大数据和物联网等技术的快速发展&#xff0c;企业面临着越来越多的数据交换和集成需求。不同系统之间的数据交换变得越来越复杂&#xff0c;而且数据量也越来越大&#xff0c;这对传统的数据交换方式提出了更高的要求。 中间件作为一种能…

把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…

2024年6月7日第十五周下午学习英语六级大纲

下午学习英语六级大纲的内容可以归纳为以下几个主要方面&#xff1a; 一、考试概述 六级考试的对象&#xff1a;修完大学英语相应阶段课程的在校大学生。考试目的&#xff1a;参照《大学英语教学指南》设定的教学目标&#xff0c;对我国大学生英语综合运用能力进行科学测量&a…

Docker 常用命令以及镜像选择

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

【Qt】QPushButton 与 QAction 的区别

1. QPushButton QPushButton 是一个界面控件&#xff0c;能显示到界面上的。QPushButton 是 QWidget的一个子类&#xff0c;是一个表示按钮的界面控件。它用于在GUI中提供一个标准的按钮&#xff0c;用户可以点击它来触发一个即时的动作或命令。按钮可以显示文本、图标或两者都…

为什么要将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…

用Python实现奇怪的疯狂按键需求

项目背景 说起来好笑,假设有一个奇怪需求 — 仅仅是假设,不代表我有这个需求,虽然可以想象有人会有这个需求,但是这个人不是我,我也不认识任何这样的人 — 疯狂向某个程序输出按键,比如,一会儿疯狂输入f,一会儿疯狂输入q。 如果是两个按键需求,我想要设置一个最简单…