数据结构----队列(Queue)的概念、队列的使用、模拟实现队列、循环队列、模拟实现循环队列、双端队列、模拟实现双端队列

文章目录

  • 1 概念
  • 2 队列的使用
  • 3 队列模拟实现
  • 4 循环队列
    • 4.1 循环队列 概念
    • 4.1 循环队列模拟实现
  • 5. 双端队列 (Deque)
  • 6 用队列实现栈
  • 7 用栈实现队列

1 概念

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

2 队列的使用

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

在这里插入图片描述
接口中提供的方法:
在这里插入图片描述
经常使用的方法:

方法功能
boolean offer(E e)入队列
E poll()出队列
E peek()获取队头元素
int size()获取队列中有效元素个数
boolean isEmpty()检测队列是否为空

注意: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());}
}

3 队列模拟实现

队列中既然可以存储元素,那底层肯定要有能够保存元素的空间,通过前面线性表的学习了解到常见的空间类型有两种:顺序结构 和 链式结构。队列的实现使用链式结构较好,并且是双向链表。
在这里插入图片描述
使用front标记队头,rear标记队尾
在这里插入图片描述
模拟实现一个双向链表,头节点first删除元素,尾节点last插入元素,可以模拟实现一个队列。

public class Queue {// 双向链表节点public static class ListNode{ListNode next;ListNode prev;int value;ListNode(int value){this.value = value;}}ListNode first;   // 队头ListNode last;    // 队尾int size = 0;// 入队列---向双向链表位置插入新节点public void offer(int e){ListNode newNode = new ListNode(e);if(first == null){first = newNode;// last = newNode;}else{last.next = newNode;newNode.prev = last;// last = newNode;}last = newNode;size++;}// 出队列---将双向链表第一个节点删除掉public int poll(){// 1. 队列为空// 2. 队列中只有一个元素----链表中只有一个节点---直接删除// 3. 队列中有多个元素---链表中有多个节点----将第一个节点删除int value = 0;if(first == null){return null;}else if(first == last){last = null;first = null;}else{value = first.value;first = first.next;first.prev.next = null;first.prev = null;}--size;return value;}// 获取队头元素---获取链表中第一个节点的值域public int peek(){if(first == null){return null;}return first.value;}public int size() {return size;}public boolean isEmpty(){return first == null;}
}

4 循环队列

4.1 循环队列 概念

那如果使用数组模拟实现队列呢?
在这里插入图片描述
此时我们需要将数组看作是循环的,来实现在0下标插入数据,那么下标4的下一个位置应该指向下标0的位置。
在这里插入图片描述
此时可以使用数组模拟实现队列,该队列为循环队列。

循环队列:

实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。
循环队列是一种基于数组实现的队列数据结构,它允许在固定大小的数组中实现队列的循环使用。循环队列解决了普通队列在出队操作后无法再次利用已出队元素的问题,通过循环利用数组空间,提高了队列的利用率。

循环队列通常包含两个指针,一个指向队列的头部(front),一个指向队列的尾部(rear)。当队列满时,rear 指针会绕回到数组的起始位置,实现数组空间的循环使用。这种设计使得循环队列的入队和出队操作的时间复杂度都为 O(1)
在这里插入图片描述

在这里插入图片描述

rear是当前可以存放数据元素的下标。

计算队列存储数据和删除数据的位置下标

数组下标循环的小技巧

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

在这里插入图片描述
2. 下标最前再往前(offset 小于 array.length): index = (index + array.length - offset) % array.length 在这里插入图片描述

如果在循环队列中存储下一个元素,数据元素存储的位置rear = (rear+1)%array.length
如果在循环队列中删除下一个元素,数据元素存储的位置front =(front+1)%array.length

区分空与满

  1. 通过添加 size 属性记录,当size等于数组长度时,队列是满的

  2. 保留一个位置,来表示满(会浪费一个空间的位置,浪费的这个空间不放元素)
    在这里插入图片描述
    如果rear = front那么队列就是空的
    如果rear的下一个元素为front,即为(rear+1)%array.length = front,那么队列就是满的。

  3. 使用标记

4.1 循环队列模拟实现

【题目链接】:622. 设计循环队列

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 == 0) ? elem.length - 1 : rear - 1;return elem[index];}public boolean isEmpty() {if (rear == front) {return true;}return false;}public boolean isFull() {return (rear + 1) % elem.length == front;}
}

5. 双端队列 (Deque)

双端队列(deque,全称double-ended queue)是一种具有队列和栈的特性的数据结构。双端队列允许从两端添加和删除元素,因此可以在队列的两端进行插入和删除操作。

双端队列可以在队列的两端进行以下操作:

  1. 从队列的前端删除元素(出队操作)
  2. 从队列的前端添加元素(入队操作)
  3. 从队列的后端删除元素
  4. 从队列的后端添加元素

双端队列可以用数组或链表实现。使用双端队列可以有效地处理需要在队列两端进行操作的问题,例如实现一个双端队列可以用来实现一个双端搜索算法。
在这里插入图片描述
在这里插入图片描述
Deque是一个接口,使用时必须创建LinkedList的对象。

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

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

6 用队列实现栈

【题目链接】:
225. 用队列实现栈
【题目描述】:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

【解题】:
入栈:将元素放入到不为空的队列中
在这里插入图片描述
出栈:
1.首先将不为空的队列中size-1个元素依次出队
2.将最后一个元素出队,该元素就是栈顶的元素
3. 重复1-2步骤,进行出栈
在这里插入图片描述
后续操作:
将45、56入栈,由于queue2不为空,将45、56放入到queue2中
在这里插入图片描述

出栈(56):
在这里插入图片描述

出栈(45):
在这里插入图片描述
出栈(23):在这里插入图片描述

出栈(12):
在这里插入图片描述
当两个队列都为空时,说明模拟的栈是空的

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

7 用栈实现队列

【题目链接】:
225. 用队列实现栈
【题目描述】:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

【解题】:
思路:借用辅助栈来实现,入队时将所有入队的元素放入辅助栈(stack1),出队时如果栈(stack2)不为空,那么就从栈(stack2)中读取数据,如果栈(stack2)为空,将辅助栈(stack1)中所有数据颠倒放入栈(stack2)中,再从栈(stack2)中读取数据。
在这里插入图片描述

class MyQueue {Stack<Integer> stack1;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()) {return stack2.pop();} else {int size = stack1.size();for (int i = 0; i < size; i++) {int x = stack1.pop();stack2.push(x);}return stack2.pop();}}public int peek() {if (empty()) {return -1;}if (!stack2.empty()) {return stack2.peek();} else {int size = stack1.size();for (int i = 0; i < size; i++) {int x = stack1.pop();stack2.push(x);}return stack2.peek();}}public boolean empty() {return stack1.empty() && stack2.empty();}
}

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

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

相关文章

LeetCode:283. 移动零

283. 移动零 1&#xff09;题目2&#xff09;代码方法一&#xff1a;两层for循环方法二&#xff1a;使用双指针 3&#xff09;结果方法一结果方法二结果 1&#xff09;题目 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的…

QT研究笔记(一)windows 开发环境安装部署

一、Qt 是什么&#xff1f; Qt 是一个跨平台的应用程序开发框架&#xff0c;最初由挪威的 Trolltech 公司开发&#xff0c;并于2008年被诺基亚收购。后来&#xff0c;Qt 框架由 Digia 公司接手&#xff0c;并在2012年成立了 The Qt Company。Qt 提供了一套丰富的工具和类库&am…

如何学习亚马逊、速卖通和阿里国际站等平台的测评自养号技术?

由于近年来各大平台纷纷开展开店政策&#xff0c;并得到国家对跨境电商的大力支持&#xff0c;吸引了众多中国卖家加入其中&#xff0c;每年呈逐渐增长的趋势。然而&#xff0c;与国内的淘宝、京东等平台不同&#xff0c;亚马逊并没有实时通讯工具和客服&#xff0c;卖家在购买…

OceanBase 4.2.2 GA 发布,全新特性快速预览!

在 2023 年度发布会上&#xff0c;OceanBase 沿着“一体化”产品战略思路&#xff0c;发布了一体化数据库的首个长期支持版本 4.2.1 LTS。作为 4.0 系列的首个 LTS 版本&#xff0c;该版本的定位是支撑客户关键业务稳定长久运行&#xff0c;我们非常认真的打磨了这个版本&#…

代码随想录算法训练营Day46|139.单词拆分、多重背包理论基础、背包问题总结

目录 139.单词拆分 方法一&#xff1a;回溯法 算法实现 方法二&#xff1a;背包问题 算法实现 多重背包理论基础 思路 算法实现 背包问题总结 前言 背包递推公式 遍历顺序 0-1背包 完全背包 139.单词拆分 题目链接 文章链接 方法一&#xff1a;回溯法 在回溯专题…

XXE基础知识整理(附加xml基础整理)

全称&#xff1a;XML External Entity 外部实体注入攻击 原理 利用xml进行读取数据时过滤不严导致嵌入了恶意的xml代码&#xff1b;和xss原理雷同 危害 外界攻击者可读取商户服务器上的任意文件&#xff1b; 执行系统命令&#xff1b; 探测内网端口&#xff1b; 攻击内网网站…

【八大排序】冒泡排序 | 快速排序 + 图文详解!!

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C语言进阶之路 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 交换排序一、冒泡排序1.1 算法步骤 动图演示1.2 冒泡排序的效率分析1.3 代码实现1.4 …

JavaScript阻止浏览器默认行为

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 浏览器对一些事件具有默认行为,例如点击链接时跳转页面,提交表单时发…

哈希表——C++

目录 一、首先使用拉链法&#xff1a; 二、开放寻址法 三、字符串哈希 1.具体如何使用进制的方式来存储字符前缀的可以看这个y总的这个图 2.接下来说一说算某个中间的区间的字符串哈希值 哈希表是一种数组之间互相映射的数据结构&#xff0c;比如举个简单的例子一个十个的数…

ArrayList常见问题

ArrayList 1、ArrayList底层的实现原理是什么 2、ArrayList list new ArrayList(10)中的list扩容几次 3、如何实现数组和list之间的转换 4、ArrayList和LinkedList的区别是什么

办公软件巨头CCED、WPS面临新考验,新款办公软件异军突起

办公软件巨头CCED、WPS的成长经历 众所周知&#xff0c;CCED和WPS在中国办公软件领域树立了两大知名品牌的地位。然而&#xff0c;它们的成功并非一朝一夕的成就&#xff0c;而是历经了长时间的发展与积淀。 在上世纪80年代末至90年代初&#xff0c;CCED作为中国大陆早期的一款…

java大学生科研创新项目在线管理系统 springboot+vue

预期成果&#xff1a; &#xff08;1&#xff09;实现一个完整的大学生科创项目在线管理系统的设计与实现&#xff0c;可以运行演示。 &#xff08;2&#xff09;预计本系统的页面完整&#xff0c;页面所有文字和图片无漏字、错字、重叠不显示的现象&#xff0c;页面所有链接和…

Unity Meta Quest MR 开发(三):Scene API 配置+实现虚拟与现实之间的碰撞

文章目录 &#x1f4d5;教程说明&#x1f4d5; Scene 配置⭐开启场景理解功能和应用访问空间数据的权限⭐OVRSceneManager⭐制作 Plane Prefab 和 Volume Prefab⭐运行场景⭐添加透视材质 &#x1f4d5;虚拟与现实物体的碰撞&#xff08;弹球 Demo&#xff09;&#x1f4d5;Mes…

web前端--------渐变和过渡

线性渐变&#xff0c;是指颜色沿一条直线进行渐变&#xff0c;例如从上到下、从左到右。 当然&#xff0c;CSS中也支持使用角度来设置渐变的方向&#xff0c;角度单位为deg。 0deg&#xff0c;为12点钟方向&#xff0c;表示从下到上渐变。 90deg&#xff0c;为3点钟方向&…

Android13源码下载及全编译流程

目录 一、源码下载 1.1、配置要求 1.1.1、硬件配置要求 1.1.2、软件要求 1.2、下载环境搭建 1.2.1、依赖安装 1.2.2、工具安装 1.2.3、git配置 1.2.4、repo配置 1.3、源码下载 1.3.1、明确下载版本 1.3.2、替换为清华源 1.3.3、初始化仓库并指定分支 1.3.4、同步全部源码 二、…

【24美赛思路已出】2024年美赛A~F题解题思路已出 | 无偿自提

A题&#xff1a;资源可用性和性别比例 问题一&#xff1a; 涉及当灯鱼种群的性别比例发生变化时&#xff0c;对更大的生态系统产生的影响。为了分析这个问题&#xff0c;可以采用以下的数学建模思路&#xff1a;建立灯鱼种群模型&#xff1a; 首先&#xff0c;建立一个灯鱼种群…

20240203在WIN10下安装Miniconda

20240203在WIN10下安装Miniconda 2024/2/3 21:06 缘起&#xff1a;最近学习stable-diffusion-webui.git&#xff0c;在Ubuntu20.04.6下配置SD成功。 不搞精简版本&#xff1a;Miniconda了。直接上Anacoda&#xff01; https://www.toutiao.com/article/7222852915286016544/ 从…

Qt 的安装以及项目的创建

目录 Qt简介Qt 开发环境安装的过程环境变量的配置Qt SDK 中的重要的工具创建一个 Qt 项目 Qt简介 开始安装教程前&#xff0c;首先来了解一下什么是QT。 QT&#xff08;Quick Thought&#xff09;是一个基于Qt库的快速应用程序开发框架。它提供了一套完整的开发工具和库&…

文本检测学习笔记_CTPN

论文地址&#xff1a;https://arxiv.org/pdf/1609.03605.pdf 开源代码&#xff1a;https://github.com/lvliguoren/pytorch_ctpn?tabreadme-ov-file 本文主要的的内容 提出了一种将文本视为由密集排列的具有固定宽度的文本候选区域组成的序列的方法。这些文本候选区域可以通…

国际国内 IT行业有哪些证书含金量高?

一、前言 在信息技术飞速发展的今天&#xff0c;IT行业证书作为衡量专业技能和知识水平的重要标准&#xff0c;越来越受到业界的重视。对于IT从业者而言&#xff0c;拥有一些权威性的证书不仅能够证明自己的专业能力&#xff0c;更是职业发展的有力助推器。基于多年的行业经验…