算法图解:如何用两个栈实现一个队列?

简介: 算法图解:如何用两个栈实现一个队列?

队列和栈是计算机中两个非常重要的数据结构,经过前面的学习(《队列》《栈》)我们知道了它们各自的特点,队列是先进先出(FIFO)的,而栈是先进后出(FILO)的,那如何用栈来实现队列呢?这可是一道经典的面试题,所以本文我们就来实现一下。

在正式开始之前,我们先来回顾一下栈和队列的常用方法。

栈(Stack)的常用方法包含以下这些:

  • push():入栈方法,向栈顶添加元素;
  • pop():出栈方法,将栈顶的元素移除并返回元素;
  • peek():查询栈顶元素,并不会移除元素。

image.png

队列(Queue)的常用方法包含以下这些:

  • offer():入队方法,向队尾添加元素;
  • poll():出队方法,从队头移除并返回元素;
  • peek():查询队头元素,并不会移除元素。

image.png

有了这些前置知识,接下来我们来看今天的题目。

题目描述

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead,分别完成在队列尾部插入整数和在队列头部删除整数的功能,若队列中没有元素,deleteHead 操作返回 -1。

示例 1:

输入:

["CQueue","appendTail","deleteHead","deleteHead"]

[[],[3],[],[]]

输出:[null,null,3,-1]

示例 2:

输入:

["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]

[[],[],[5],[2],[],[]]

输出:[null,-1,null,null,5,2]

提示:

1 <= values <= 10000

最多会对 appendTail、deleteHead 进行 10000 次调用

leetcode:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/


解题思路

这道题目的意思其实很好理解,就是要将先进后出的栈改为先进先出的队列,其实问题中也给出了一些提示,“用两个栈来实现一个队列”。这道题实现的核心思想就是「负负得正」,我们先用一个栈来存入元素(这时最先进入的元素在栈底),然后再将第一个栈中的元素移动到新栈中,此时最先进入的元素就在栈顶了,然后在用第二个栈出栈时,整个执行的顺序就变成了先进先出。

接下来,我们用图解的方式来实现一下整个流程。


步骤一

先将元素入栈到第一个栈中,如下图所示:

image.png

步骤二

将第一个栈中的元素都移动到第二个栈中,如下图所示:

image.png

步骤三

所有元素从第二个栈中出栈,如下图所示:

image.png

小结

从上述图片可以看出,元素添加顺序是 1、2、3,最终经过两个栈之后的出栈顺序也是 1、2、3,这样我们就通过两个栈实现了队列(先进先出)。

image.png

实现代码

接下来我们就用代码来实现一下以上思路:

class CQueue {
    Stack<Integer> inputStack; // 入栈的容器(添加时操作)
    Stack<Integer> outputStack; // 出栈和查询的栈容器
    public CQueue() {
        inputStack = new Stack();
        outputStack = new Stack();
    }
    // 添加操作
    public void appendTail(int value) {
        inputStack.push(value);
    }
    // 删除操作
    public int deleteHead() {
        if (!outputStack.isEmpty()) {
            // 出栈容器不为空
            return outputStack.pop();
        } else if (!inputStack.isEmpty()) {
            // 入栈 stack 全部转移到出栈 stack
            while (!inputStack.isEmpty()) {
                outputStack.push(inputStack.pop());
            }
        }
        return outputStack.isEmpty() ? -1 : outputStack.pop();
    }
}


我们在 LeetCode 中提交以上测试代码,执行结果如下:

image.png

注意事项

在整个实现过程中有两个小细节需要特别注意一下:

  1. 第 1 个栈只负责入栈(暂存数据),第 2 个栈只负责出栈(最终的队列执行顺序);
  2. 每次栈 2 出栈时都要把所有的元素都出完之后,才能从栈 1 中追加(添加)新数据,当栈 2 的数据没有全部出栈完成时,不能将栈 1 的元素入栈到栈 2,这样会导致元素的执行顺序混乱。


总结

本文我们通过两个先进后出的栈,通过“负负得正”的思路实现了队列先进先出的特性,但需要特别注意的是当第 2 个栈也就是出栈容器,在非空(栈)时不能将第 1 个栈中的元素添加到第 2 个栈中,以免造成程序执行顺序混乱。


相关文章
|
2月前
|
算法
【算法】栈
栈相关算法题,供参考,附有链接地址及板书
|
3月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
4月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
181 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
4月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
73 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
4月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
51 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
4月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
92 3
|
4月前
|
算法 C++
【算法单调栈】 矩形牛棚(C/C++)
【算法单调栈】 矩形牛棚(C/C++)
|
1天前
|
传感器 算法
基于GA遗传算法的多机无源定位系统GDOP优化matlab仿真
本项目基于遗传算法(GA)优化多机无源定位系统的GDOP,使用MATLAB2022A进行仿真。通过遗传算法的选择、交叉和变异操作,迭代优化传感器配置,最小化GDOP值,提高定位精度。仿真输出包括GDOP优化结果、遗传算法收敛曲线及三维空间坐标点分布图。核心程序实现了染色体编码、适应度评估、遗传操作等关键步骤,最终展示优化后的传感器布局及其性能。
|
1天前
|
机器学习/深度学习 算法 安全
基于深度学习的路面裂缝检测算法matlab仿真
本项目基于YOLOv2算法实现高效的路面裂缝检测,使用Matlab 2022a开发。完整程序运行效果无水印,核心代码配有详细中文注释及操作视频。通过深度学习技术,将目标检测转化为回归问题,直接预测裂缝位置和类别,大幅提升检测效率与准确性。适用于实时检测任务,确保道路安全维护。 简介涵盖了算法理论、数据集准备、网络训练及检测过程,采用Darknet-19卷积神经网络结构,结合随机梯度下降算法进行训练。
|
2天前
|
算法 数据可视化 数据安全/隐私保护
一级倒立摆平衡控制系统MATLAB仿真,可显示倒立摆平衡动画,对比极点配置,线性二次型,PID,PI及PD五种算法
本课题基于MATLAB对一级倒立摆控制系统进行升级仿真,增加了PI、PD控制器,并对比了极点配置、线性二次型、PID、PI及PD五种算法的控制效果。通过GUI界面显示倒立摆动画和控制输出曲线,展示了不同控制器在偏转角和小车位移变化上的性能差异。理论部分介绍了倒立摆系统的力学模型,包括小车和杆的动力学方程。核心程序实现了不同控制算法的选择与仿真结果的可视化。
31 15

热门文章

最新文章