news 2026/7/25 15:38:57

使用两个栈来实现一个队列

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用两个栈来实现一个队列

在 Java 中,利用两个栈实现队列的核心思路是通过栈的“后进先出”特性模拟队列的“先进先出”特性:将一个栈(stackIn)作为“入队栈”,专门处理入队操作;另一个栈(stackOut)作为“出队栈”,专门处理出队/获取队首操作。只有当stackOut为空时,才将stackIn的所有元素转移到stackOut,从而实现“先进先出”。

核心原理

  1. 入队(offer):直接将元素压入stackIn(O(1) 时间复杂度)。
  2. 出队(poll)
    • stackOut为空,将stackIn中所有元素依次弹出并压入stackOut(此时stackOut的栈顶就是队列的队首元素);
    • 弹出stackOut的栈顶元素(即队列的队首元素)。
  1. 获取队首(peek):逻辑与poll类似,但仅获取stackOut的栈顶元素,不弹出。
  2. 判空(isEmpty):当stackInstackOut都为空时,队列为空。

完整代码实现

import java.util.Stack; /** * 用两个栈实现队列 */ public class QueueByTwoStacks { // 入队栈:专门处理入队操作 private Stack<Integer> stackIn; // 出队栈:专门处理出队/获取队首操作 private Stack<Integer> stackOut; // 初始化 public QueueByTwoStacks() { stackIn = new Stack<>(); stackOut = new Stack<>(); } /** * 入队操作:直接压入入队栈 * @param x 要入队的元素 */ public void offer(int x) { stackIn.push(x); } /** * 出队操作:弹出队首元素 * @return 队首元素 * @throws RuntimeException 队列为空时抛出异常 */ public int poll() { // 先检查出队栈是否为空,为空则转移入队栈的元素 transferIfNeeded(); // 若仍为空,说明队列为空 if (stackOut.isEmpty()) { throw new RuntimeException("队列为空,无法执行poll操作"); } // 弹出出队栈的栈顶(队列的队首) return stackOut.pop(); } /** * 获取队首元素(不弹出) * @return 队首元素 * @throws RuntimeException 队列为空时抛出异常 */ public int peek() { // 先检查出队栈是否为空,为空则转移入队栈的元素 transferIfNeeded(); // 若仍为空,说明队列为空 if (stackOut.isEmpty()) { throw new RuntimeException("队列为空,无法执行peek操作"); } // 获取出队栈的栈顶(队列的队首) return stackOut.peek(); } /** * 判断队列是否为空 * @return 空返回true,否则返回false */ public boolean isEmpty() { return stackIn.isEmpty() && stackOut.isEmpty(); } /** * 辅助方法:当出队栈为空时,将入队栈的所有元素转移到出队栈 */ private void transferIfNeeded() { if (stackOut.isEmpty()) { while (!stackIn.isEmpty()) { stackOut.push(stackIn.pop()); } } } // 测试示例 public static void main(String[] args) { QueueByTwoStacks queue = new QueueByTwoStacks(); // 入队:1 -> 2 -> 3 queue.offer(1); queue.offer(2); queue.offer(3); // 输出队首:1 System.out.println("队首元素:" + queue.peek()); // 出队:1 System.out.println("出队元素:" + queue.poll()); // 输出队首:2 System.out.println("队首元素:" + queue.peek()); // 出队:2 System.out.println("出队元素:" + queue.poll()); // 入队:4 queue.offer(4); // 出队:3 System.out.println("出队元素:" + queue.poll()); // 出队:4 System.out.println("出队元素:" + queue.poll()); // 判空:true System.out.println("队列是否为空:" + queue.isEmpty()); } }

代码说明

  1. 栈的选择:直接使用 Java 内置的Stack类(也可使用Deque接口的LinkedList实现,Deque是栈的推荐替代方案,Stack是旧版类)。
  2. 核心辅助方法transferIfNeeded()封装了“入队栈转出队栈”的逻辑,避免代码冗余,仅在stackOut为空时触发转移,保证效率。
  3. 异常处理pollpeek操作时,若队列为空则抛出运行时异常,符合队列的常规行为。
  4. 判空逻辑:必须同时判断stackInstackOut,因为可能存在“入队栈有元素但出队栈为空”的中间状态。

时间复杂度

  • offer(入队):O(1)(直接压栈)。
  • poll/peek(出队/获取队首)
    • 均摊复杂度 O(1):每个元素最多被“压入stackIn→ 弹出stackIn→ 压入stackOut→ 弹出stackOut”四次,分摊到每个操作上为 O(1);
    • 最坏复杂度 O(n):当stackOut为空时,需要转移n个元素(n为入队栈的元素数)。

关键总结

  • 双栈实现队列的核心是“分栈职责 + 按需转移”:入队只操作stackIn,出队只操作stackOut,仅当stackOut为空时才转移元素,避免重复转移。
  • 与双队列实现栈相比,双栈实现队列的均摊时间复杂度更优(pop/peek 为均摊 O(1)),实际开发中更常用。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/24 22:48:14

vLLM 0.11.0 发布:全面移除 V0 引擎,性能与多模态支持再升级

vLLM 0.11.0 发布&#xff1a;全面移除 V0 引擎&#xff0c;性能与多模态支持再升级 在大模型推理系统持续演进的今天&#xff0c;架构统一和效率提升已成为决定技术落地成败的关键。vLLM 0.11.0 的发布正是这一趋势下的里程碑式突破——V0 推理引擎正式退出历史舞台&#xff…

作者头像 李华
网站建设 2026/7/23 17:05:03

从零开始:使用Git安装TensorRT及其依赖组件

从零开始&#xff1a;使用Git安装TensorRT及其依赖组件 在智能摄像头实时识别行人、车载系统毫秒级响应路况的今天&#xff0c;AI模型的“推理速度”早已不再是锦上添花的优化项&#xff0c;而是决定产品能否落地的关键瓶颈。许多团队在PyTorch或TensorFlow中训练出高精度模型后…

作者头像 李华
网站建设 2026/7/23 4:17:39

模块十八.集合

1.集合框架&#xff08;单列集合&#xff09;2.Collection接口3.迭代器1.迭代器基本使用NoSuchElementException:没有可操作的元素异常2.迭代器底层原理1.获取Iterator的时候怎么获取的&#xff1a;Iterator iterator list.iterator( )我们知道Iterator是一个接口&#xff0c;…

作者头像 李华
网站建设 2026/7/23 13:27:32

FLUX.1-dev服装生成LoRA模型体验

FLUX.1-dev服装生成LoRA模型体验 最近在折腾一个基于 FLUX.1-dev 的服装设计 LoRA&#xff0c;结果有点上头。 这玩意儿真能靠一句话就把衣服从概念变出来——不是那种“看着像”的模糊轮廓&#xff0c;而是连丝绸反光的方向、刺绣纹样的走势、拉链位置的合理性都能交代清楚。你…

作者头像 李华
网站建设 2026/7/23 19:43:35

使用nexus3搭建自己的制品服务器

使用nexus3搭建自己的制品服务器 需求 云原生开发&#xff0c;有个新的需求&#xff0c;就是docker制品服务器&#xff0c;对于私域的开发&#xff0c;公有云的服务器不合适&#xff0c;只能自己搭建了。 所以记录一下搭建一个docker镜像服务器的过程&#xff0c;完成的功能…

作者头像 李华
网站建设 2026/7/24 18:48:26

38、Linux 邮件与网页浏览实用指南

Linux 邮件与网页浏览实用指南 在 Linux 系统中,邮件管理和网页浏览是日常使用中非常重要的功能。下面将详细介绍相关的工具和操作方法。 邮件管理 查看邮件文件夹 可以使用 less 查看邮件文件夹,也能在文本编辑器中编辑。不过,文件夹会显示为一个包含所有邮件的长滚动…

作者头像 李华