数据结构:队列

特点

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

手搓一个队列 

 

链式队列

 

开始动手

队列属于插入元素后需要从头部来删除,我们可以用双链表来模拟它

尾巴进,头部出 

接下来整个的过程跟双链表差不多,大家可以参考我之前一篇博客

链表(3):双链表_cx努力编程中的博客-CSDN博客

初始化 

    static class ListNode{public int val;public ListNode next;public ListNode prev;public ListNode(int val){this.val = val;}}public ListNode head;public ListNode last;public int usedSize;

offer

尾插法

    public boolean offer(int val){ListNode node = new ListNode(val);if(head == null){head = node;last = node;}else{last.next = node;node.prev = last;last = last.next;}usedSize++;return true;}

poll

    public int poll(){//没有节点if(head == null){return -1;}int retVal = head.val;//只有一个节点if(head.next == null){head = null;last = null;return retVal;}//两个及以上的节点head = head.next;head.prev = null;usedSize--;return retVal;}

peek

    public int peek(){if(head == null){return -1;}return head.val;}

empty和size

    public boolean empty(){return head == null;}public int size(){return usedSize;}

数组队列

622. 设计循环队列 - 力扣(LeetCode)

简单介绍一下

假设有一个容量为5的数组,要操作12 23 34 45 56 67 78 7个数字

队头front,队尾rear先放在0位置,分别往后遍历

每次加入一个元素rear就++,每次弹出一个元素front就++

 

但是这会出现一个问题

当我们加到56这个元素之后,rear跑到数组外面去了,越界了

极限一点,当我们把当前队列的元素全部poll之后,front也跑到数组外面去了

其实队列弹出元素后,前面的必然会是空的,我们可以让rear走到前面来

整个队列弹空了之后也把front移到前面的空格处

如图,我们依次往队列加45 56 12 23 34,此时rear走到数组末端,我们把45弹出,rear就可以重新回到数组头

这么一看,整个数组队列就是一个循环,一个圈

 

🆗我们依次加入元素,每次加入rear就往后走

rear走了一圈又和front相遇了,此时问题来了

1. 队列此时是空的还是满的?

(1)使用usedSize来记录,放入一个元素usedSize++

(2)浪费一个空间来表示满

相当于你要过河,总得扔个石头试试深浅的道理一样,在front前面开辟一块空间,什么元素都不放,当rear走到这块空间时,判断一下rear下一个元素位置是不是front,是的话就证明队列满了

(3)使用标记

第一次相遇(起始位置)标记一下,第二次相遇的时候就证明它满了

2. rear怎么从7下标来到0下标?

公式:rear = (rear + 1) % len

front = (front + 1) % len

    public boolean isEmpty() {return front == rear;}public boolean isFull() {return (rear+1) % elem.length == front;}

入队和出队

    public MyCircularQueue(int k) {elem = new int[k];}//入队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];}

得到队尾元素的部分要注意一下,不能直接rear-1,因为如果rear=0的时候,rear-1=-1是不合法的

🆗你以为结束了吗?当我们把这段代码放入到力扣里面,我们发现报错了,报错结果:

在执行3的入队操作时,预期的是true,而我们输出了false

当我们空间为3的时候,确实只能存2个元素,因为存第3个元素空间会被浪费

那我们可以投机地改一下代码

或者使用usedSize,就没有浪费空间这么一说了

代码具体就是定义完usedSize,enQueue就usedSize++,deQueue就usedSize--


双端队列

指的是在队列两边都可以进行入队和出队的操作

链式队列就能实现这个功能

 

那数组队列也可以实现吗

ArrayDeque的底层也是有这些头插尾插方法的

 

这两个不仅仅可以当作队列,也可以当作栈。这两个当作栈的情况比较多


队列题目

225. 用队列实现栈 - 力扣(LeetCode)

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

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

我们知道,队列和栈的出栈顺序本来就是矛盾的,所以一个队列实现不了栈,但是两个队列可以啊

假设我们要操作12 23 34 45这四个数,把前3个数加入后,栈要弹出元素,就是34第一个出

 

观察到qu2队列是空的,那qu1就把12和23分别弹出来扔到qu2里面存储起来,qu1再把34弹出,这样就实现了栈弹出34的操作

解题步骤:

1.入栈:哪个队列不为空就放到哪个队列里面,两个都为空就扔到qu1里面

2.出栈:哪个队列不为空就出size-1个元素,并扔到空队列里面

3.当两个队列都为空的时候,栈就是空的

整个代码

class MyStack {private Queue<Integer> qu1;private Queue<Integer> qu2;public MyStack() {qu1 = new LinkedList<>();qu2 = new LinkedList<>();}public void push(int x) {if(!qu1.isEmpty()){qu1.offer(x);}else if(!qu2.isEmpty()){qu2.offer(x);}else{//两个队列都是空的,指定放到qu1里面qu1.offer(x);}}public int pop() {if(empty()){return -1;}if(!qu1.isEmpty()){int size1 = qu1.size();//让一个size1记录qu1的大小,防止循环的时候循环条件里的size没有变化for (int i = 0; i < size1-1; i++) {int x = qu1.poll();qu2.offer(x);}return qu1.poll();}else{int size2 = qu2.size();for (int i = 0; i < size2-1; i++) {int x = qu2.poll();qu1.offer(x);}return qu2.poll();}}public int top() {if(empty()){return -1;}if(!qu1.isEmpty()){int size1 = qu1.size();int x = -1;for (int i = 0; i < size1; i++) {x = qu1.poll();qu2.offer(x);}return x;}else{int x = -1;int size2 = qu2.size();for (int i = 0; i < size2; i++) {x = qu2.poll();qu1.offer(x);}return x;}}public boolean empty() {return qu1.isEmpty() && qu2.isEmpty();}
}


232. 用栈实现队列 - 力扣(LeetCode)

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

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

和上面那道题同理,一个栈实现不了队列,所以我们要用两个栈

1.入队的时候,放到s1里面

2.出队的时候,都出s2当中的元素,当s2没有元素的时候,把s1里面的元素全部倒过来

整个的代码:

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.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();}
}

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

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

相关文章

c#设计模式-行为型模式 之 备忘录模式

&#x1f680;简介 备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为型设计模式&#xff0c;它保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象。所谓备忘录模式就是在不破坏封装的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象…

Matlab-ODE45:求解状态变量(微分方程组)

ode45函数 ode45实际上是数值分析中数值求解微分方程组的一种方法&#xff0c;4阶五级Runge-Kutta算法。 调用方法 ​ 其实这种方程的每一个状态变量都是t 的函数&#xff0c;我们可以从现代控制理论的状态空间来想。因此返回[ t , x ]&#xff0c;其中t是一个列向量&#xf…

Hadoop3教程(十一):MapReduce的详细工作流程

文章目录 &#xff08;94&#xff09;MR工作流程Map阶段Reduce阶段 参考文献 &#xff08;94&#xff09;MR工作流程 本小节将展示一下整个MapReduce的全工作流程。 Map阶段 首先是Map阶段&#xff1a; 首先&#xff0c;我们有一个待处理文本文件的集合&#xff1b; 客户端…

机器学习——奇异值分解二(特征分解+SVD纯理解)

矩阵的特征分解 特征值和特征向量的定义 抄来的&#xff1a;奇异值分解 困惑1&#xff1a;特征值和特征向量&#xff0c;和原矩阵是怎样的关系&#xff0c;需要一个栗子进行更具象的认识 困惑2&#xff1a;为什么多个特征向量组合成的矩阵&#xff0c;可以构成矩阵A的特征分解…

自动驾驶中的数据安全和隐私

自动驾驶技术的发展已经改变了我们的出行方式&#xff0c;但伴随着这项技术的普及&#xff0c;数据安全和隐私问题也变得愈发重要。本文将探讨自动驾驶中的数据收集、数据隐私和安全挑战&#xff0c;以及如何保护自动驾驶系统的数据。 自动驾驶中的数据收集 在自动驾驶技术中…

【Wifi】Wifi架构介绍

Wifi架构介绍 本文基于Android介绍其Wifi架构。Wifi是许多操作系统提供的重要功能之一&#xff0c;特别是越来越多的车载系统wifi是其必备功能。为啥wifi是必备功能&#xff1f; 一方面是传统的上网&#xff08;现在有些车载使用DCM模块管理网络&#xff09;&#xff0c;另一方…

Spring MVC 和Spring JDBC

目录 Spring MVC MVC模式 核心组件 工作流程 Spring JDBC Spring JDBC功能和优势 Spring JDBC的关键组件 Spring MVC Spring MVC&#xff08;Model-View-Controller&#xff09;是Spring框架的一个模块&#xff0c;用于构建Web应用程序。它的主要目标是将Web应用程序的不…

B2R Raven: 2靶机渗透

B2R Raven: 2靶机渗透 视频参考&#xff1a;ajest &#xff1a;https://www.zhihu.com/zvideo/1547357583714775040?utm_id0 原文参考&#xff1a;ajest &#xff1a;https://zhuanlan.zhihu.com/p/270343652 文章目录 B2R Raven: 2靶机渗透1 启动靶机&#xff0c;查看后网卡…

CocosCreator 面试题(十一)Cocos Creator 屏幕适配

Cocos Creator 提供了多种屏幕适配的方式&#xff0c;以确保游戏在不同设备上能够正确显示和布局。 以下是 Cocos Creator 中常用的屏幕适配方式及其说明。 1、 Cocos Creator 项目设置中统一配置设计分辨率和屏幕适配 在同一个项目里的多个 Canvas 的设计分辨率仍然采用同一…

HBuilder创建uniapp默认项目导入uview(胎教)

1&#xff1a;更新HBuilder 建议更新 2&#xff1a;更新插件 我本人在没有更新插件的情况下报错了&#xff0c;找到了**这个大佬**解决问题&#xff0c;所以建议更新插件 先卸载uni-app&#xff08;Vue2&#xff09;编译 再重新安装 uni-app&#xff08;Vue2&#xff09;…

qemu基础篇——VSCode 配置 GDB 调试

文章目录 VSCode 配置 GDB 调试安装 VSCode 插件调试文件创建调试配置配置脚本qemu 启动脚 启动调试报错情况一报错情况二报错情况三 调试界面运行 GDB 命令查看反汇编断点查看内核寄存器查看变量参考链接 VSCode 配置 GDB 调试 qemu-基础篇——arm 裸机调试环境搭建 上一节中…

LuaJit交叉编译移植到ARM Linux

简述 Lua与LuaJit的主要区别在于LuaJIT是基于JIT&#xff08;Just-In-Time&#xff09;技术开发的&#xff0c;可以实现动态编译和执行代码&#xff0c;从而提高了程序的运行效率。而Lua是基于解释器技术开发的&#xff0c;不能像LuaJIT那样进行代码的即时编译和执行。因此&…

利用ChatGPT练习口语

目录 ChatGPT 这两天发布了一个激动人心的新功能&#xff0c;App端&#xff08;包括iOS和Android&#xff09;开始支持语音对话以及图片识别功能。 这两个功能一如既往的优先开放给Plus用户使用&#xff0c;现在将App更新到最新版本&#xff0c;就能体验。 为什么说激动人心&a…

2023年中国汽车智能工厂市场规模不断增大,智能化已成趋势[图]

汽车智能工厂是在数字化工厂的基础上&#xff0c;通过互联网技术与工业技术结合&#xff0c;数据监管设备以及AI等技术的结合&#xff0c;实现汽车整车从原材料及零部件的生产到运输、组装一系列的自动化生产。汽车智能工厂很大程度上降低成本和人为干扰&#xff0c;实现自动化…

19 | 如何搞清楚事务、连接池的关系?正确配置是怎样的

事务的基本原理 在学习 Spring 的事务之前&#xff0c;你首先要了解数据库的事务原理&#xff0c;我们以 MySQL 5.7 为例&#xff0c;讲解一下数据库事务的基础知识。 我们都知道 当 MySQL 使用 InnoDB 数据库引擎的时候&#xff0c;数据库是对事务有支持的。而事务最主要的作…

2018-2019 ACM-ICPC, Asia Nanjing Regional Contest G. Pyramid(组合数学 计数)

题目 t(t<1e6)组样例&#xff0c;每次给定一个n(n<1e9)&#xff0c;统计边长为n的上述三角形的等边三角形个数 其中等边三角形的三个顶点&#xff0c;可以在所有黑色三角形&白色三角形的顶点中任取&#xff0c; 答案对1e97取模 思路来源 申老师 & oeis A0003…

Unity引擎:收费模式和服务升级,为游戏开发带来更多可能性

Unity 引擎的收费模式和配套服务升级已经引起了广泛的关注和讨论。自 2024 年 1 月 1 日起&#xff0c;Unity 将根据游戏的安装量对开发者进行收费。这将会影响到很多游戏开发者和玩家。本文将探讨 Unity 引擎的收费模式和配套服务更新&#xff0c;以及对游戏开发者和玩家的影响…

报道 | 2023-2024年1月国际运筹优化会议汇总

2023年10月、11月、12月召开会议汇总&#xff1a; 2023 International Conference on Optimization and Applications (ICOA) Location: Abu Dhabi, United Arab Emirates Important dates: Conference: October 05-06, 2023 Details: https://lct.ac.ae/en/icoa/ 2023 INF…

python项目之AI动物识别工具的设计与实现(django)

项目介绍&#xff1a; &#x1f495;&#x1f495;作者&#xff1a;落落 &#x1f495;&#x1f495;个人简介&#xff1a;混迹java圈十余年&#xff0c;擅长Java、小程序、Python等。 &#x1f495;&#x1f495;各类成品java毕设 。javaweb&#xff0c;ssm&#xff0c;spring…

Java调用FFmpeg

Java调用FFmpeg 1、FFmepg基础知识1.1 下载 FFmpeg1.2 FFmpeg 工具使用 2、Java使用2.1 FFmpeg源码编译2.2 Java集成FFmpeg2.2.1 JNI2.2.2 Java调用执行 FFmpeg 工具 命令 1、FFmepg基础知识 About FFmpeg ffmpeg(计算机程序) - 百度百科 FFmpeg/FFmpeg - GitHub CSDN&#xf…