队列

什么是队列

是一种线性的数据结构,和栈不同,队列遵循“先进先出”的原则。如下图所示:
在这里插入图片描述

在这里插入图片描述
在集合框架中我们可以看到LinkedList类继承了Queue类(队列)。

普通队列(Queue)

Queue中的方法

方法功能
add()入队列
offer()入队列
remove()出队列
poll()出队列
element()获取队头元素
peek()获取队头元素

add()和offer()都是添加数据、remove()和poll()都是删除数据、element()和peek()都是获取队列头部元素信息这些方法有什么区别呢?(下面都是豆包总结的,可以参考一下)
在这里插入图片描述
在这里插入图片描述
总结:
add()、remove()、element()方法对于满和空队列的时候会抛出异常。而offer()、poll()、peek()方法不会,它们更具有灵活性。我们则常用offer()、poll()、peek()方法来对队列进行操作。

其他方法

在Collection接口中还有size()、isEmpty()等其他方法我们可以使用。

模拟实现队列

用链表实现

在这里插入图片描述

public class MyQueue {static class ListNode{private final int val;private ListNode next;private ListNode prev;private ListNode(int val) {this.val = val;}}public ListNode first;public ListNode last;/*** 入队操作:尾插法* @param val*/public void offer(int val) {ListNode node = new ListNode(val);if(empty()) {first = last = node;}last.next = node;node.prev = last;last = last.next;}/*** 出队操作:删除头节点* @return*/public int poll() {if(empty()) {return -1;}int value = first.val;if(first == last) {first = last = null;return value;}else {first = first.next;first.prev = null;return first.val;}}/*** 获得头节点不删除* @return*/public int peek() {if(empty()) {return -1;}return first.val;}/*** 获得有效数据* @return*/public int size() {ListNode cur = first;int usedSize = 0;while (cur != null) {usedSize++;cur = cur.next;}return usedSize;}/*** 判断是否为空* @return*/public boolean empty() {return first == null;}
}

循环队列

对于普通的数组来说,再用队列的思想时,很容易造成数组下标越界等问题。这时候我们可以将数组循环起来。如下图所示:
在这里插入图片描述
这时候就产生问题了。

1、rear 和 front 如何访问从最后一个下标访问到0下标?

由于循环,可以将(下标+偏移量)/ length。这里的偏移量为1(每次只走一格)。也就是对于有关下标的需要用(rear+1) / len(front+1) / len

2、如何判断数组是否满了。

解决的方法有:
1、使用size个数,当等于数组长度,则说明满了;
2、用一个boolean值来标记是否满了。初始时,front == rearisFull == false。当每次添加数据时判断 front == rear,当相等时isFull == true,说明满了。在删除数据时,不可能满了,将isFull == false
3、留出一个空间来判断是否满了。当rear的下一个是front的时候,就说明是满的。
在这里插入图片描述
在入队时,放一个元素,rear往后走,一开始 rear == front。当rear的下一个是front的时候,也就只存放了 len - 1个数据。

代码展示:

采用预留空间的方法

class MyCircularQueue {public int[] elem;int rear = 0;int front = 0;public MyCircularQueue(int k) {elem = new int[k];//由于采用预留空间的方法,使得实际数据只有k - 1个}/*** 向循环列队中插入一个元素* @param value* @return*/public boolean enQueue(int value) {if(isFull()) {return false;}elem[rear] = value;//rear指向预留的空间rear = (rear + 1) % elem.length;//这样rear下标始终控制在合理范围return true;}/*** 删除循环列队中的一个元素* 由于队列是先进先出的,所以删除的是front下标的元素* @return*/public boolean deQueue() {if(isEmpty()) {return false;}front = (front + 1) % elem.length;//这样front下标始终控制在合理范围return true;}/*** 从队首获取元素* @return*/public int Front() {if(isEmpty()) {return -1;}return elem[front];}/*** 获取队尾元素* @return*/public int Rear() {if(isEmpty()) {return -1;}//rear并不是队尾元素,rear的上一个才是。//rear - 1就得到了,但当rear为0时,rear - 1 就会越界,这时候就要if判断了if(rear == 0) {return elem[elem.length - 1];}return elem[rear - 1];}/*** 判断循环队列是否为空* @return*/public boolean isEmpty() {return rear == front;}/*** 判断循环队列是否满了* @return*/public boolean isFull() {return (rear + 1) % elem.length == front;//rear为预留空间,下一个指向front}
}

双端队列(Deque)

它是一种特殊的队列,允许在队列的两端进行元素的插入与删除操作。这意味着既能在队列头部添加或移除元素,也能在队列尾部添加或移除元素。一般创建ArrayDequeLinkedList这两个类的对象。
ArrayDeque是用数组实现的双端队列,LinkedList是用双向链表实现的双端队列。其中的优缺点和顺序表与链表的优缺点类似。
对于双端队列的方法是在Queue方法名中后面加上Last、First(例如:offerFirst()、pollFirst()、peekLast()等,但要注意的是:对于抛异常的获取元素并不是用的element()而是getFirst()和getLast() )。

代码展示:

public static void test1() {Deque<Integer> deque = new ArrayDeque<>();deque.offerFirst(1);deque.offerFirst(10);deque.offerFirst(100);deque.offerFirst(1000);deque.offerLast(2);deque.offerLast(20);System.out.println(deque);deque.pollFirst();//出队列的头元素:1000System.out.println(deque);deque.pollLast();//出队列的尾元素:20System.out.println(deque);System.out.println(deque.peekFirst());System.out.println(deque.peekLast());System.out.println(deque);
}
public static void test2() {Deque<Integer> deque = new LinkedList<>();deque.offerFirst(1);deque.offerFirst(10);deque.offerFirst(100);deque.offerFirst(1000);deque.offerLast(2);deque.offerLast(20);System.out.println(deque);deque.pollFirst();//出队列的头元素:1000System.out.println(deque);deque.pollLast();//出队列的尾元素:20System.out.println(deque);System.out.println(deque.peekFirst());System.out.println(deque.peekLast());System.out.println(deque);
}

ArrayDequeLinkedList两个实现的效果是一样的。

用队列实现栈

首先一个队列肯定是实现不了栈的,两个运行逻辑都不一样,一个先进先出,一个先进后出。此时需要两个队列来实现栈。
在这里插入图片描述
对于出"栈"方法:将其余数据依次放入空队列中(对非空队列进行出"栈"操作)。
在这里插入图片描述
对于入"栈",只需要将元素放入非空的队列中即可。
在这里插入图片描述
对于拿到"栈"顶的元素,前面和出"栈"一样:将其余数据依次放入空队列中,直接输出剩下的元素,在将剩下的元素放到另一个队列中。
在这里插入图片描述

代码展示:

import java.util.LinkedList;
import java.util.Queue;class MyStack {public Queue<Integer> queue1;public Queue<Integer> queue2;public MyStack() {queue1 = new LinkedList<>();queue2 = new LinkedList<>();}/*** 入栈* @param x*/public void push(int x) {if(!queue1.isEmpty()) {queue1.offer(x);}else if(!queue2.isEmpty()) {queue2.offer(x);}else {queue1.offer(x);}}/*** 出栈* @return*/public int pop() {//当都为空时,说明"栈"中没有元素if(empty()) {return -1;}//对于非空队列进行操作if(!queue1.isEmpty()) {int size = queue1.size();//将其余元素移到空队列while (size != 1) {queue2.offer(queue1.poll());size--;}//返回队列中仅有的元素,并删除return queue1.poll();}else {//下面是!queue2.isEmpty()的情况int size = queue2.size();while (size != 1) {queue1.offer(queue2.poll());size--;}return queue2.poll();}}/*** 获取"栈"顶元素* @return*/public int top() {//判断栈是否为空if(empty()) {return -1;}if(!queue1.isEmpty()) {int size = queue1.size();while (size != 1) {queue2.offer(queue1.poll());size--;}//上述操作和出栈一样,下面只需输出元素,并不删除数据int value = queue1.poll();queue2.offer(value);//将元素入队,避免丢失return value;}else {int size = queue2.size();while (size != 1) {queue1.offer(queue2.poll());size--;}int value = queue2.poll();queue1.offer(value);return value;}}public boolean empty() {return queue1.isEmpty() && queue2.isEmpty();//当队列都为空时,说明"栈"为空}
}

用栈实现队列

同样的,也是需要两个栈的。
在这里插入图片描述
对于出"队列",只需要将非空栈(stack1)中的元素全部放到另一个栈中(stack2),再从stack2中出元素。
在这里插入图片描述
当stack2为空,则将stack1全部放入stack2中。
在这里插入图片描述
对于入"队列"来说,只需要将元素放到stack1中。
在这里插入图片描述

代码展示:

import java.util.Stack;class MyQueue {public Stack<Integer> stack1;public Stack<Integer> stack2;public MyQueue() {stack1 = new Stack<>();stack2 = new Stack<>();}public void push(int x) {stack1.push(x);}public int pop() {if(empty()) {return -1;}if (stack2.empty()) {while (!stack1.empty()) {//需要将stack1中的元素 全部 放到stack2中(用while循环)stack2.push(stack1.pop());}}return stack2.pop();//stack2栈中有元素,直接调用方法}public int peek() {if(empty()) {return -1;}if (stack2.empty()) {while (!stack1.empty()) {stack2.push(stack1.pop());}}return stack2.peek();}public boolean empty() {return stack1.empty() && stack2.empty();}
}

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

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

相关文章

Nginx — 防盗链配置

防盗链简述 防盗链是一种保护网络资源所有者权益的技术手段&#xff0c;旨在防止未经授权的用户或网站通过直接链接的方式盗用资源&#xff0c;以下是关于防盗链的简述&#xff1a; 原理 基于请求头验证&#xff1a;服务器通过检查请求头中的特定字段&#xff0c;如Referer字…

【浅学】Windows下ffmpeg+nginx+flv将本地视频推流在本地搭建的Web前端页面中播放,超详细步骤

Nginx安装和配置 下载nginx-1.19.3-http-flv 模块预编译包并解压放在d盘&#xff0c;路径就跟安装步骤里说的一样(如下图)&#xff0c;不然会有其他问题出现。 打开conf/nginx.conf&#xff0c;查看RTMP和http相关的配置&#xff0c;确认端口号和路由名称 ffpemg推流视频…

Ubuntu-tomcat安装部署

https://blog.csdn.net/weixin_43877427/article/details/144697087 Linux下Tomcat安装与配置_tomcat linux安装及配置教程-CSDN博客 一、下载Tomcat 1、官网下载 进入后根据自己需要选择不同的版本&#xff0c;点击download 进入后&#xff0c;在下图标注的里边选择要下载…

希洛激活器策略思路

在复杂多变的外汇市场中&#xff0c;交易者常常寻求有效的工具来辅助决策。 希洛激活器作为一种综合性的技术指标&#xff0c;结合了江恩理论、CCI&#xff08;商品通道指数&#xff09;和MACD&#xff08;移动平均收敛发散指标&#xff09;&#xff0c;旨在为交易者提供更为全…

n8n工作流自动化平台的实操:本地化高级部署

一、本地高级部署 1.下载 docker pull docker.n8n.io/n8nio/n8n 2.运行 docker volume create n8n_data docker run -dit --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n -e N8N_SECURE_COOKIEfalse -e N8N_RUNNERS_ENABLEDtrue -e N8N_ENFORCE_SETTINGS_FIL…

vector和string的迭代器

1. 迭代器的本质 (1) 标准要求 C 标准要求 std::string 和 std::vector 的迭代器必须是 随机访问迭代器&#xff08;Random Access Iterator&#xff09;。 指针天然满足随机访问迭代器的所有操作&#xff08;如 、--、n、* 等&#xff09;&#xff0c;因此可以直接用指针实现…

PyCharm代理配置全攻略:系统设置+Python运行环境一键搞定

文章目录 1. 设置系统代理1.1 作用范围1.2 使用场景1.3 设置步骤 2. 设置 python 运行/调试代理2.1 作用范围2.2 使用场景2.3 设置步骤 Pycharm 工具作为一款强大的 IDE&#xff0c;其代理配置在实际开发中也是必不可少的&#xff0c;下面介绍下如何配置 Pycharm 的代理。 1. …

stm32 g031g8 flash擦除函数被坑

先记录一下在擦除的时候由于调用了这个FLASH_PageErase(FLASH_BANK_1, secpos); 导致擦除不成功&#xff0c;写入失败。 下面的擦除有问题// 使用 FLASH_PageErase 擦除该页while ((FLASH->SR & FLASH_SR_BSY1) ! 0); // 等待空闲FLASH_PageErase(FLASH_BANK_1, secpo…

深度学习与 PyTorch 基础

笔记 1 深度学习简介 1.1 深度学习概念 深度学习是机器学习的一类算法, 以人工神经网络为结构, 可以实现自动提取特征 深度学习核心思想是人工神经网络为结构, 自动提取特征 1.2 深度学习特点 自动提取特征 解释性差 大量数据和高性能计算能力 非线性转换(引入非线性因…

【Unity】XLua访问C#文件

创建NPC.cs&#xff1a; public class NPC { public string name; public int age; public void Say() { Debug.Log("Say:我是未被修改的"); } public static void Say() { Debug.Log("Static Say:我是未被修改的"); } public void Say2(int a) { Debug.Lo…

【第十六届蓝桥杯省赛】比赛心得与经验分享(PythonA 组)

文章目录 一、我的成绩二、我的备赛经历三、如何备赛&#xff08;个人观点&#xff09;1. 基础语法2. 数据结构3. 算法4. 数学 四、做题技巧与注意事项五、我的题解试题A 偏蓝 &#x1f3c6;100%试题B IPV6 &#x1f3c6;0%试题C 2025图形 &#x1f3c6;100%试题D 最大数字 &am…

基于Springboot+Mysql的校园博客系统(含LW+PPT+源码+系统演示视频+安装说明)

系统功能 管理员功能&#xff1a;首页、个人中心、博主管理、文章分类管理、文章信息管理、举报投诉管理、系统管理&#xff1b;博主功能&#xff1a;首页、个人中心、文章信息管理、举报投诉管理、我的收藏管理&#xff1b;前台首页功能&#xff1a;首页、文章信息、系统公告…

第三次作业(密码学)

#include <stdio.h> #include <stdlib.h> // 计算最大公约数 int gcd(int a, int b) { while (b ! 0) { int temp b; b a % b; a temp; } return a; } // 计算模幂运算 int mod_pow(int base, int exponent, int modulus) { …

3.0/Q1,Charls最新文章解读

文章题目&#xff1a;Association between outdoor artificial light at night and metabolic diseases in middle-aged to older adults-the CHARLS survey DOI&#xff1a;10.3389/fpubh.2025.1515597 中文标题&#xff1a;夜间户外人工光与中老年人代谢性疾病的关联-CHARLS调…

MATLAB 中zerophase函数——零相位响应

零相位响应&#xff08;Zero-Phase Response&#xff09;是指滤波器的幅度函数&#xff0c;但相位为零。滤波器的相位响应为零&#xff0c;意味着不同频率的信号通过滤波器后&#xff0c;其相位不发生任何变化&#xff0c;即信号的波形在时间轴上没有偏移。 零相位响应指的是当…

马克思最基本的哲学思想--改造世界以实现人的自由全面发展--deepseek

马克思的哲学思想可以概括为“改造世界以实现人的自由全面发展”&#xff0c;这句话看似简单&#xff0c;却包含了其哲学的核心逻辑。我们可以从三个层面展开分析&#xff1a; 1. “改造世界”——实践是哲学的终极使命 马克思在《关于费尔巴哈的提纲》中写道&#xff1a; “哲…

JAVA学习-练习试用Java实现“一个简单的文本摘要系统 :基于关键词提取或句子摘要”

问题&#xff1a; java语言编辑&#xff0c;实现一个简单的文本摘要系统 &#xff1a;基于关键词提取或句子摘要。 解答思路&#xff1a; 实现一个简单的文本摘要系统&#xff0c;我们可以采用基于关键词提取的方法。以下是一个简单的Java实现&#xff0c;使用TF-IDF&#xff0…

案例解析:基于量子计算的分子对接-QDOCK(Quantum Docking)

分子对接&#xff08;Moleculardocking&#xff09;在药物发现中具有重要意义&#xff0c;但对接的计算速度和准确率始终难以平衡&#xff0c;其巨大解搜索空间对传统计算机来说异常艰巨。 本文通过引入网格点匹配&#xff08;GPM, Grind point matching&#xff09;和特征原子…

【Mytais系列】Datasource模块:数据源连接

MyBatis 的 DataSource 模块是框架与数据库交互的核心基础设施&#xff0c;负责管理数据库连接的创建、分配、释放及池化&#xff0c;直接影响 SQL 执行效率和资源利用率。以下是其核心内容、功能及在 SQL 执行中的作用详解&#xff1a; 一、DataSource 模块的核心组件 组件 功…

React 组件prop添加类型

给函数的props做注解 import { useState } from reacttype Props { className:string,title?:string } // 自定义一个Button组件 function Button(props:Props){// 解构出classname\const {className} propsreturn <button className{className}>点击我</button&g…