队列的概念及使用

目录

一. 概念

二. 队列的使用

 三. 队列模拟实现

四. 循环队列

五. 面试题


一. 概念

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

Java 中, Queue 是个接口,底层是通过链表实现 的。

在Queue接口的方法里, 我们看到有add remove element 这些是继承于Collection接口的, 而offer poll peek是接口本身的,他们的使用效果基本一致

二. 队列的使用

注意:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。 

public static void main ( String [] args ) {
        Queue < Integer > q = new LinkedList <> ();
        q . offer ( 1 );
        q . offer ( 2 );
        q . offer ( 3 );
        q . offer ( 4 );
        q . offer ( 5 ); // 从队尾入队列
        System . out . println ( q . size ());
        System . out . println ( q . peek ()); // 获取队头元素
        q . poll ();
        System . out . println ( q . poll ()); // 从队头出队列,并将删除的元素返回
        if ( q . isEmpty ()){
                System . out . println ( " 队列空 " );
        } else {
                System . out . println ( q . size ());
        }
}

 三. 队列模拟实现

队列中既然可以存储元素,那底层肯定要有能够保存元素的空间,通过前面线性表的学习了解到常见的空间类型有两种:顺序结构 和 链式结构 。显然实现队列用链式结构更好, 但是用单链表还是双向链表呢?
如果使用单链表, 从队尾进, 想要找到队尾, 则需遍历一遍链表, 或需要用last指针指向队尾, 从队头出, 则需将头结点向后移动
显然, 使用双向链表更加方便.
(LinkedList 可以看做: 双向链表 栈 队列)
public class MyQueue {static class ListNode{public int val;public ListNode prev;public ListNode next;public ListNode(int val){this.val = val;}}public ListNode head;public ListNode last;//入队public void offer(int val){ListNode node = new ListNode(val);if(head == null){head = last = node;}else{last.next = node;node.prev = last;last = node;}}//出队public int poll(){if(empty()){return -1;}int val;if(head.next == null){val = head.val;head = null;last = null;return val;}val = head.val;head = head.next;head.prev = null;return val;}public boolean empty(){return head == null;}public int peek(){if(head ==null){return -1;}return head.val;}
}

四. 循环队列

实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。
环形队列通常使用数组实现。

数组下标循环的小技巧

 

队尾指针向后:

rear = (rear + 偏移量) %array.length

队尾指针向前:

rear = (rear + array.length - 偏移量) %array.length

如何区分空与满
1. 通过添加 size 属性记录
2. 保留一个位置, 浪费一个空间

设计一个循环队列 链接

class MyCircularQueue {public int[] elem;public int front;public int rear;public MyCircularQueue(int k) {elem = new int[k+1];}//入队public boolean enQueue(int value) {if(isFull()){return false;}elem[rear] = value;rear = (rear+1)%elem.length;return true;}//删除队头元素public boolean deQueue() {if(isEmpty()){return false;}front = (front + 1)%elem.length;return true;}//得到队头元素public int Front() {if(isEmpty()){return -1;}return elem[front];}//得到队尾元素public int Rear() {if(isEmpty()){return -1;}int index = (rear + elem.length - 1)%elem.length;return elem[index];}public boolean isEmpty() {return front == rear;}public boolean isFull() {return (rear + 1)%elem.length == front;}
}

五. 双端队列

双端队列( deque )是指允许两端都可以进行入队和出队操作的队列, deque “double ended queue” 的简称。
那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

 Deque是一个接口,使用时必须创建LinkedList的对象。

在实际工程中,使用 Deque 接口是比较多的,栈和队列均可以使用该接口。
Deque<Integer> stack = new ArrayDeque<>();// 双端队列的线性实现
Deque<Integer> queue = new LinkedList<>();// 双端队列的链式实现

五. 面试题

1. 用队列实现栈 链接

思路:一个队列是不能实现栈的, 需要用两个队列

1. 入栈, 当两个队列都为空时, 放在第一个队列里

2. 再次入栈时, 放在不为空的队列

3. 出栈时, 出不为空的队列, 出size-1个元素, 剩下的一个就是要出栈的元素

代码:

class MyStack {private Queue<Integer> qu1;private Queue<Integer> qu2;public MyStack() {qu1 = new LinkedList<>();qu2 = new LinkedList<>();}public void push(int x) {if(empty()){qu1.offer(x);return;}if(!qu1.isEmpty()){qu1.offer(x);}else{qu2.offer(x);}}public int pop() {if(empty()){return -1;}if(!qu1.isEmpty()){int size = qu1.size();for(int i = 0;i < size-1;i++){qu2.offer(qu1.poll());}return qu1.poll();}else{int size = qu2.size();for(int i = 0;i < size-1;i++){qu1.offer(qu2.poll());}return qu2.poll();}}public int top() {if(empty()){return -1;}if(!qu1.isEmpty()){int size = qu1.size();for(int i = 0;i < size-1;i++){qu2.offer(qu1.poll());}int tmp = qu1.peek();qu2.offer(qu1.poll());return tmp;}else{int size = qu2.size();for(int i = 0;i < size-1;i++){qu1.offer(qu2.poll());}int tmp = qu2.peek();qu1.offer(qu2.poll());return tmp;}}public boolean empty() {return qu1.isEmpty() && qu2.isEmpty();}
}

2. 用栈实现队列 链接

思路:一个栈不能实现队列, 需要两个栈

1. 入队, 把数据放在第一个栈

2. 出栈, 出第二个栈的栈顶元素即可, 如果第二个栈为空, 将里面的所有元素放到第二个栈

3. 当两个栈都为空时, 说明模拟的队列为空

class MyQueue {private Stack<Integer> s1;private Stack<Integer> s2;public MyQueue() {s1 = new Stack<>();s2 = new Stack<>();}public void push(int x) {s1.push(x);}public int pop() {if(empty()){return -1;}if(s2.isEmpty()){while(!s1.isEmpty()){s2.push(s1.pop());}}return s2.pop();}public int peek() {if(empty()){return -1;}if(s2.isEmpty()){while(!s1.isEmpty()){s2.push(s1.pop());}}return s2.peek();}public boolean empty() {return s1.isEmpty() && s2.isEmpty();}
}

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

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

相关文章

IDEA基础——Maven配置tomcat

配置方案 一、配置maven-tomcat plugin插件&#xff08;只最高支持到tomcat 8&#xff09;~~1.添加镜像源&#xff0c;获取tomcat 8插件配置~~~~1.1 在pom.xml里先添加镜像源~~~~1.2 添加tomcat插件配置~~ 2. 添加tomact官方发布的插件配置&#xff08;无需添加镜像源&#xff…

本届挑战赛季军方案:基于图网络及LLM AGENT的微服务系统异常检测和根因定位方法

aiboco团队荣获本届挑战赛季军。该团队来自亿阳信通。 方案介绍 本届挑战赛采用开放式赛题&#xff0c;基于建行云龙舟运维平台的稳定性工具和多维监控系统&#xff0c;模拟大型的生活服务APP的生产环境&#xff0c;提供端到端的全链路的日志、指标和调用链数据。参赛队伍在组…

vue中将某个不太规则的json转成对象,或者将对象转成json字符串

vue中将某个不太规则的json转成对象&#xff0c;或者将对象转成json字符串 以我自己做的项目某个不规则的json为例 将json对象转成json字符串&#xff1a; JSON.stringify(jsonData); 将不规则json字符串转成对象并获取对应的属性的值&#xff1a; JSON.parse(jsonData).Name…

云原生精品资料合集(附下载)

云计算是产业数字化转型的关键基础设施,以基础设施资源为中心的云搬迁时代接近尾声&#xff0c;以应用价值为中心的云原生时代已经到&#xff0c;所以IT人员学习云原生正当时&#xff01;最近跟各位大神征集了云原生的教程&#xff0c;行业报告和最佳实践&#xff0c;总有一款适…

蓝桥杯_中断系统

一 中断 中断&#xff0c;即cpu暂停执行当前程序&#xff0c;转而执行另外一段特殊程序&#xff0c;处理结束后。返回之前暂停程序继续执行。 中断向量&#xff0c;中断服务程序的入口地址&#xff0c;每个中断源都对应一个固定的入口地址。 中断服务函数&#xff0c;内核响应中…

【亚马逊云科技】通过Amazon CloudFront(CDN)快速访问资源

文章目录 前言一、应用场景二、【亚马逊云科技】CloudFront&#xff08;CDN&#xff09;的优势三、入门使用总结 前言 前面有篇文章我们介绍了亚马逊云科技的云存储服务。云存储服务主要用于托管资源&#xff0c;而本篇文章要介绍的CDN则是一种对托管资源的快速访问服务&#…

Socket网络编程(二)——UDP快速入门

目录 UDP相关概念UDP是什么为什么不可靠UDP能做什么UDP包最大长度 UDP单播、广播、多播概念1. 单播、广播、多播模型图2. ip地址分类3. 子网掩码的作用&#xff1a;4. 广播地址5. 网段划分6. 变长子网掩码 UDP核心APIAPI-DatagramSocketDatagramSocket构造方法DatagramSocket常…

6.5 共享数据

本节介绍Android的四大组件之一ContentProvider的基本概念和常见用法&#xff1a;首先说明如何使用内容提供器封装内部数据的外部访问接口&#xff0c;然后阐述如何使用内容解析器通过外部接口操作内部数据&#xff0c;最后叙述如何利用内容解析器读写联系人信息&#xff0c;以…

10_Vue

文章目录 Vue快速入门Vue的指令Vue的插值表达式V指令v-bind&#xff08;单向绑定&#xff09;v-model&#xff08;双向绑定&#xff09;v-on&#xff08;事件监听&#xff09;v-for&#xff08;循环&#xff09;v-text、v-htmlv-show&#xff08;显示/隐藏&#xff09;v-if&…

了解GPT:ChatGPT的终极指南

在人工智能&#xff08;AI&#xff09;的世界里&#xff0c;有一颗冉冉升起的新星正在革命性地改变我们与机器的交互方式&#xff1a;ChatGPT。在本文中&#xff0c;我们将深入研究什么是ChatGPT&#xff0c;为什么底层技术GPT如此强大&#xff0c;以及它是如何实现其卓越功能的…

excel导出标准化

虽然标题叫标准化&#xff0c;只不过是我自己的习惯&#xff0c;当一件事情变得流程标准化之后&#xff0c;开发程序就会飞快&#xff0c;开发评估工作总是 搞个1~2天&#xff0c;实则前端后端一起开发&#xff0c;1个小时就可以搞定。 1 前端 const exportXls async () >…

C++重点---STL简介

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、STL简介 STL&#xff08;Standard Template Library&#xff09;是C标准库中的一个重要组成部分&#xff0c;它提供了…

iOS中卡顿产生的主要原因及优化思路

卡顿本质上是一个UI体验上的问题&#xff0c;而UI的渲染及显示&#xff0c;主要涉及CPU和GPU两个层面。若 CPUGPU渲染耗时超过16.7ms&#xff0c;就会在屏幕vsync信号到来时无法更新屏幕内容&#xff0c;进而导致卡顿。 iOS中UI渲染主要包含Layout->Draw->Prepare->Co…

MySQL5.7.44版本压缩包在Win11系统快速安装

一.背景 主要还是为了公司的带徒弟任务。我自己也喜欢MySQL的绿色版本。 1.软件版本说明 MySQL版本&#xff1a;5.7.44 压缩包版本&#xff0c;相当于绿色版。当然&#xff0c;你也可以使用window系统的Installer版本去安装。 操作系统&#xff1a;Win11家庭版 二.MySQL软…

electron-release-server部署electron自动更新服务器记录

目录 一、前言 环境 二、步骤 1、下载上传electron-release-server到服务器 2、宝塔新建node项目网站 3、安装依赖 ①npm install ②安装并配置postgres数据库 ③修改项目配置文件 ④启动项目 ⑤修改postgres的认证方式 ⑥Cannot find where you keep your Bower p…

spring6学习笔记

1.环境准备 1.idea建立一个空项目&#xff0c;jdk要求是17 2.Maven配置&#xff08;和mybatis里一样&#xff09; 3.新建一个模块 2.ocp原则 3.依赖倒置原则&#xff08;DIP&#xff09; 什么是依赖倒置原则? 1.面向接口编程&#xff0c;面向抽象编程&#xff0c;不要面向…

【React 报错】—Remove untracked files, stash or commit any changes, and try again.

【React 报错】—Remove untracked files, stash or commit any changes, and try again. 在react项目中通过.less文件进行样式定义&#xff0c;先暴露webpack配置文件&#xff0c;执行命令&#xff1a;yarn eject 或 npm run eject&#xff0c;报错如下&#xff1a; 原因是因…

【清理mysql数据库服务器二进制日志文件】

清理前后比对 清理前占用 86% &#xff1a; 清理后占用 29% &#xff1a; 排查占用磁盘较大的文件 检测磁盘空间占用 TOP 10 # 检测磁盘空间占用 TOP 10 $ sudo du -S /var/log/ | > sort -rn | # -n选项允许按数字排序。-r选项会先列出最大数字&#xff08;逆序&#x…

vue中 input disable后无法触发点击事件

问题&#xff1a;input标签为disabled后&#xff0c;点击事项无效&#xff1b;当点击文字**“请选择”**时无法触发点击事件&#xff0c;其父标签的其余位置均可触发 解决&#xff1a;只需要在input标签中添加 style“pointer-events:none” 即可 pointer-events: none 作用是…

如何刷新 DNS 缓存 (macOS, Linux, Windows)

如何刷新 DNS 缓存 (macOS, Linux, Windows) Unix Linux Windows 如何刷新 DNS 缓存 (macOS, FreeBSD, RHEL, CentOS, Debian, Ubuntu, Windows) 请访问原文链接&#xff1a;https://sysin.org/blog/how-to-flush-dns-cache/&#xff0c;查看最新版。原创作品&#xff0c;转载…