Java数据结构队列

队列(Queue)
 

概念

队列的使用

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

import java.util.LinkedList;
import java.util.Queue;public class Test {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());}}
}

队列的模拟实现

队列中既然可以存储元素,那底层肯定要有能够保存元素的空间,通过前面线性表的学习了解到常见的空间类型有两种:顺序结构(数组) 和 链式结构

队列的实现使用顺序结构还是链式结构好?

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 = last.next;}}//头删public int poll() {if (head == null) {return -1;}int ret = head.val;if (head.next == null) {head = null;last = null;} else {head = head.next;head.prev = null;}return ret;}public int peek() {if (head == null) {return -1;}int ret = head.val;return ret;}
}

循环队列

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

如何区分空与满

1. 通过添加 size 属性记录

空:size=0    满:us=数组长度

2. 保留一个位置(浪费一个空间)(下面的设计循环队列用的就是此方法)

相遇就是空 满:last的下一个是first
3. 使用标记

Boolean flag

数组下标循环的小技巧

1. 下标最后再往后(offset 小于 array.length): index = (index + offset) % array.length

 

2. 下标最前再往前(offset 小于 array.length): index = (index + array.length - offset) % array.length

设计循环队列

class MyCircularQueue {public int[] elem;public int first;public int last;public MyCircularQueue(int k) {elem = new int[k];}public boolean enQueue(int value) {if (isFull()) {return false;}elem[last] = value;last = (last + 1) % elem.length;return true;}public boolean deQueue() {if (isEmpty()) {return false;}first = (first + 1) % elem.length;return true;}//得到队头元素public int Front() {if (isEmpty()) {return -1;}return elem[first];}//得到队尾元素public int Rear() {if (isEmpty()) {return -1;}int index = (last == 0) ? elem.length - 1 : last - 1;return elem[index];}public boolean isEmpty() {return first == last;}public boolean isFull() {return (last + 1) % elem.length == first;}
}/*** Your MyCircularQueue object will be instantiated and called as such:* MyCircularQueue obj = new MyCircularQueue(k);* boolean param_1 = obj.enQueue(value);* boolean param_2 = obj.deQueue();* int param_3 = obj.Front();* int param_4 = obj.Rear();* boolean param_5 = obj.isEmpty();* boolean param_6 = obj.isFull();*/

将elem = new int[k];改为elem = new int[k+1];即可

双端队列

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

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

在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口

Deque<Integer> stack = new ArrayDeque<>();//双端队列的线性实现
Deque<Integer> queue = new LinkedList<>();//双端队列的链式实现

面试题

1.用队列实现栈

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<>();}public void push(int x) {if (empty()) {queue1.offer(x);return;}if (!queue1.isEmpty()) {queue1.offer(x);} else {queue2.offer(x);}}public int pop() {if (empty()) {return -1;}if (!queue1.isEmpty()) {int size = queue1.size();for (int i = 0; i < size - 1; i++) {queue2.offer(queue1.poll());}return queue1.poll();} else {int size = queue2.size();for (int i = 0; i < size - 1; i++) {queue1.offer(queue2.poll());}return queue2.poll();}}public int top() {if (empty()) {return -1;}if (!queue1.isEmpty()) {int size = queue1.size();int ret = -1;for (int i = 0; i < size; i++) {ret = queue1.poll();queue2.offer(ret);}return ret;} else {int size = queue2.size();int ret = -1;for (int i = 0; i < size; i++) {ret = queue2.poll();queue1.offer(ret);}return ret;}}public boolean empty() {return queue1.isEmpty() && queue2.isEmpty();}
}/*** Your MyStack object will be instantiated and called as such:* MyStack obj = new MyStack();* obj.push(x);* int param_2 = obj.pop();* int param_3 = obj.top();* boolean param_4 = obj.empty();*/

2.用栈实现队列

import java.util.Stack;class MyQueue {public Stack<Integer> s1;public 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.empty()) {while (!s1.empty()) {s2.push(s1.pop());}}return s2.pop();}public int peek() {if (empty()) {return -1;}if (s2.empty()) {while (!s1.empty()) {s2.push(s1.pop());}}return s2.peek();}// 判断模拟实现的队列是否为空public boolean empty() {return s1.empty() && s2.empty();}
}/*** Your MyQueue object will be instantiated and called as such:* MyQueue obj = new MyQueue();* obj.push(x);* int param_2 = obj.pop();* int param_3 = obj.peek();* boolean param_4 = obj.empty();*/

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

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

相关文章

敏感信息泄露漏洞

法律声明 参与培训需要遵守国家法律法规&#xff0c;相关知识只做技术研究&#xff0c;请勿用于违法用途&#xff0c;造成任何后果自负与本人无关。 中华人民共和国网络安全法&#xff08;2017年6月1日起施行&#xff09; 第二十二条 任何个人和组织不得从事入侵他人网络、干扰…

基于SpringBoot+Vue的OA管理系统

一、项目背景介绍&#xff1a; 办公自动化&#xff08;Office Automation&#xff0c;简称OA&#xff09;&#xff0c;是将计算机、通信等现代化技术运用到传统办公方式&#xff0c;进而形成的一种新型办公方式。办公自动化利用现代化设备和信息化技术&#xff0c;代替办公人员…

LangChain-09 Query SQL DB With RUN GPT 查询数据库 并 执行SQL 返回结果

安装依赖 pip install --upgrade --quiet langchain-core langchain-community langchain-openai编写代码 from langchain_core.prompts import ChatPromptTemplate from langchain_community.utilities import SQLDatabase from langchain_core.output_parsers import StrO…

python 02字符串

字符串可能是用到最多的数据类型了&#xff0c;所有标准序列操作&#xff08;索引、切片、乘法、成员资格检查、长度、最小值和最大值&#xff09;都适用于字符串 但别忘了字符串是不可变的&#xff0c;因此所有的元素赋值和切片赋值都是非法的。 1.居中效果 默认为空格 可…

Redis集群三种模式

一、Redis集群的三种模式 Redis有三种模式&#xff0c;分别是主从复制、哨兵模式、cluster 主从复制:主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均衡和简单的故障…

基于springboot的社区医疗服务系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

JavaScript实现全选、反选功能(Vue全选、反选,js原生全选、反选)

简介&#xff1a; 在JavaScript中&#xff0c;实现全选和反选通常是通过操作DOM元素和事件监听来实现&#xff1b; 全选功能&#xff1a;当用户点击一个“全选”复选框时&#xff0c;页面中所有具有相同类名的复选框都将被选中&#xff1b; 反选功能&#xff1a;用户点击一个…

2024.4.2-[作业记录]-day07-CSS 盒子模型(显示模式、盒子模型)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业 2024.4.2 学习笔记CSS标签元素显示模式1 块元素2 行内元素3 行内块元素4…

C++从入门到精通——初步认识面向对象及类的引入

初步认识面向对象及类的引入 前言一、面向过程和面向对象初步认识C语言C 二、类的引入C的类名代表什么示例 C与C语言的struct的比较成员函数访问权限继承默认构造函数默认成员初始化结构体大小 总结 前言 面向过程注重任务的流程和控制&#xff0c;适合简单任务和流程固定的场…

Java栈和队列的实现

目录 一.栈(Stack) 1.1栈的概念 1.2栈的实现及模拟 二.队列(Queue) 2.1队列的概念 2.2队列的实现及模拟 2.3循环队列 2.4双端队列&#xff08;Deque&#xff09; 一.栈(Stack) 1.1栈的概念 栈:一种特殊的线性表&#xff0c;其 只允许在固定的一端进行插入和删除元素操作…

Tailwind 4.0 即将到来:前端开发的“速度与激情”

随着前端开发技术的不断进步&#xff0c;我们每天都在寻找更快、更简洁的解决方案来提升我们的开发效率和用户体验。今天&#xff0c;我要为大家介绍一项令人振奋的新技术进展——Tailwind 4.0的来临&#xff01; 对于经常使用Tailwind的朋友们来说&#xff0c;这个消息无疑是激…

【Kaggle】练习赛《鲍鱼年龄预测》(上)

前言 上一篇文章&#xff0c;讲解了《肥胖风险的多类别预测》机器学习方面的文章&#xff0c;主要是多分类算法的运用&#xff0c;本文是一个回归的算法&#xff0c;本期是2024年4月份的题目《Regression with an Abalone Dataset》即《鲍鱼年龄预测》&#xff0c;在此分享高手…