news 2026/8/2 1:31:20

使用两个队列实现一个栈

作者头像

张小明

前端开发工程师

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

在 Java 中,利用两个队列实现栈的核心思路是通过队列的“先进先出”特性模拟栈的“后进先出”特性:始终让一个队列(记为queue1)存储栈的所有元素,另一个队列(记为queue2)作为临时中转。以下是完整的实现思路和代码示例:

核心原理

  1. 入栈(push):直接将元素添加到主队列queue1
  2. 出栈(pop):将queue1中除最后一个元素外的所有元素依次转移到queue2,弹出queue1中剩余的最后一个元素(即栈顶元素),然后交换queue1queue2的角色(让queue2变为空的中转队列)。
  3. 获取栈顶(peek):逻辑与pop类似,但转移后不弹出最后一个元素,而是记录其值后再将其转移到queue2,最后交换队列角色。
  4. 判空(isEmpty):直接判断主队列queue1是否为空。

完整代码实现

import java.util.LinkedList; import java.util.Queue; /** * 用两个队列实现栈 */ public class StackByTwoQueues { // 主队列:存储栈的所有元素 private Queue<Integer> queue1; // 临时中转队列 private Queue<Integer> queue2; // 初始化 public StackByTwoQueues() { // 推荐使用LinkedList作为Queue的实现(LinkedList实现了Deque,支持队列操作) queue1 = new LinkedList<>(); queue2 = new LinkedList<>(); } /** * 入栈:直接添加到主队列 * @param x 要入栈的元素 */ public void push(int x) { queue1.offer(x); } /** * 出栈:弹出栈顶元素(最后入队的元素) * @return 栈顶元素 * @throws RuntimeException 栈为空时抛出异常 */ public int pop() { if (isEmpty()) { throw new RuntimeException("栈为空,无法执行pop操作"); } // 将queue1中除最后一个元素外的所有元素转移到queue2 while (queue1.size() > 1) { queue2.offer(queue1.poll()); } // 弹出queue1中剩余的最后一个元素(栈顶) int top = queue1.poll(); // 交换两个队列的角色:让queue1重新作为主队列,queue2为空 Queue<Integer> temp = queue1; queue1 = queue2; queue2 = temp; return top; } /** * 获取栈顶元素(不弹出) * @return 栈顶元素 * @throws RuntimeException 栈为空时抛出异常 */ public int peek() { if (isEmpty()) { throw new RuntimeException("栈为空,无法执行peek操作"); } // 逻辑同pop,但保留最后一个元素 while (queue1.size() > 1) { queue2.offer(queue1.poll()); } int top = queue1.peek(); // 将最后一个元素也转移到queue2 queue2.offer(queue1.poll()); // 交换队列角色 Queue<Integer> temp = queue1; queue1 = queue2; queue2 = temp; return top; } /** * 判断栈是否为空 * @return 空返回true,否则返回false */ public boolean isEmpty() { return queue1.isEmpty(); } // 测试示例 public static void main(String[] args) { StackByTwoQueues stack = new StackByTwoQueues(); // 入栈:1 -> 2 -> 3 stack.push(1); stack.push(2); stack.push(3); // 输出栈顶:3 System.out.println("栈顶元素:" + stack.peek()); // 出栈:3 System.out.println("出栈元素:" + stack.pop()); // 输出栈顶:2 System.out.println("栈顶元素:" + stack.peek()); // 出栈:2 System.out.println("出栈元素:" + stack.pop()); // 出栈:1 System.out.println("出栈元素:" + stack.pop()); // 判空:true System.out.println("栈是否为空:" + stack.isEmpty()); } }

代码说明

  1. 队列选择:使用LinkedList实现Queue接口(LinkedList支持队列的offer/poll/peek操作,效率高)。
  2. 异常处理poppeek操作时,若栈为空则抛出运行时异常,符合栈的常规行为。
  3. 队列交换:每次pop/peek后交换queue1queue2的引用,避免重复创建队列,节省内存。

时间复杂度

  • push:O(1)(直接入队)。
  • pop/peek:O(n)(需要转移 n-1 个元素,n 为栈的大小)。

优化思路(可选)

若希望降低pop/peek的时间复杂度,可改用一个队列 + 记录栈顶的方式:

  • 入栈时直接入队,并记录栈顶。
  • 出栈时,将队列前 n-1 个元素依次出队并重新入队,最后弹出第 n 个元素(栈顶)。
    这种方式仅需一个队列,核心逻辑与双队列一致,但代码更简洁。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/2 1:06:54

华为云相较于其他友商的优势!

华为云相较于其他云服务提供商&#xff0c;具备以下优势 1.**技术自主性** **自主研发**:华为云基于自研芯片(如鲲鹏、昇腾)和操作系统(如鸿蒙、欧拉)&#xff0c;确保技术自主可控&#xff0c;减少对外部技术的依赖。**全栈技术能力**:提供从芯片到云服务的全栈解决方案&#…

作者头像 李华
网站建设 2026/8/1 9:08:00

Ascend C高性能LayerNorm融合算子开发实战

目录 &#x1f4cb; 摘要 &#x1f3d7;️ 技术原理 2.1 架构设计理念解析&#xff1a;CANN的异构计算哲学 2.2 核心算法实现&#xff1a;从数学公式到硬件指令 2.3 性能特性分析&#xff1a;从理论算力到实际吞吐 &#x1f527; 实战部分 3.1 完整可运行代码示例 3.2 …

作者头像 李华
网站建设 2026/8/1 23:07:30

MIL-STD-1553B总线仿真应用解析

1553B总线协议 1553B总线介绍 MIL-STD-1553B&#xff08;GJB 289A&#xff09;是一种应用于机载电子设备间通信的共享式总线通信协议&#xff0c;以总线式拓扑结构连接最多31个终端设备互联&#xff0c;传输速率为1Mbps&#xff0c;在航空电子总线网络中占有重要地位&#xff…

作者头像 李华
网站建设 2026/8/1 22:43:59

震惊!云服务器选错损失千万,这3家专业机构必须知道!

震惊&#xff01;云服务器选错损失千万&#xff0c;这3家专业机构必须知道&#xff01; 在数字化转型浪潮席卷各行各业的今天&#xff0c;云服务器已成为企业运营不可或缺的数字基石。然而&#xff0c;一个看似简单的选择背后&#xff0c;可能隐藏着巨大的商业风险。从数据安全…

作者头像 李华
网站建设 2026/8/1 2:03:29

34、跨平台文件操作与系统提醒工具使用指南

跨平台文件操作与系统提醒工具使用指南 在日常的计算机使用中,我们常常会遇到跨平台文件操作以及需要系统提醒的场景。本文将详细介绍如何在不同操作系统之间进行文件转换、操作Macintosh磁盘,以及如何利用系统工具进行日期时间显示、日历查看和日程管理等。 1. Macintosh磁…

作者头像 李华
网站建设 2026/8/1 19:04:49

vLLM-Omni发布:高效全模态模型服务框架

vLLM-Omni发布&#xff1a;高效全模态模型服务框架 在大模型从实验室走向千行百业的今天&#xff0c;一个现实问题正困扰着越来越多的企业&#xff1a;如何以合理的成本&#xff0c;稳定地支撑高并发、低延迟的生成式 AI 服务&#xff1f;许多团队发现&#xff0c;即便拥有强大…

作者头像 李华