You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现栈最小值移至栈顶操作时触发EmptyStackException异常

问题描述

实现Integer类型栈的操作:查找栈中的最小元素,将其移动至栈顶位置,其余元素的相对顺序保持不变。约定栈的序列最左侧元素为栈顶、最右侧元素为栈底,例如初始栈[1 2 3 4 5]经过findSmallest方法处理后,应当得到结果栈[2 3 4 5 1]。当前调用该方法后打印栈内容时,程序抛出EmptyStackException空栈异常。

原有问题代码如下:

import java.util.Scanner;
import java.util.Stack;

public class StackTest {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        Stack<Integer> stack1 = new Stack<>();
        for (int i = 0; i < 5; i++) {
            stack1.push(input.nextInt());
        }

        System.out.println("------------------");
        findSmallest(stack1);
        for (int i = 0; i < 5; i++) {
            System.out.println(stack1.pop());
        }
    }

    public static void findSmallest(Stack<Integer> stack1) {

        Stack<Integer> stack2 = new Stack<>();
        Integer min = stack1.peek();
        int i = 0;
        while(i < 5) {
            if(stack1.peek() < min)
                min = stack1.peek();
            stack2.push(stack1.pop());
            i++;
        }
        int j = 0;
        while (j < 5) {
            if(!(stack2.peek().equals(min)))
                stack1.push(stack2.pop());
            j++;
        }
        stack1.push(min);
        stack2.pop();
    }
}
错误原因
  • 第二个元素转移循环逻辑有缺陷:循环固定执行5次,但仅当临时栈stack2的栈顶元素不等于最小值时才执行弹出操作,遇到最小值时不弹出元素仅累加计数,导致循环结束后stack2中除最小值外的其余4个元素都没有移回原栈stack1,原栈仅在后续操作中压入了1个最小值元素,总元素个数只有1个。
  • main方法中固定循环5次执行pop(),原栈只有1个元素,第一次弹出后栈已为空,后续4次弹出操作直接触发EmptyStackException。
  • 代码硬编码栈长度为5,通用性差,栈长度变化时会直接出现逻辑错误。
  • 方法末尾多余的stack2.pop()操作无实际业务意义,极端场景下也可能触发空栈异常。
修复后代码

修复逻辑:

  1. 移除硬编码的长度判断,改用栈本身的size()方法获取元素总数,适配任意长度的栈。
  2. 从临时栈往原栈转移元素时,无论元素是否为最小值都先弹出临时栈,遇到最小值时标记已找到、不压入原栈,其余元素正常压入原栈,保证所有非最小值元素都能正确移回。
  3. 移除多余的弹出操作,所有非最小值元素转移完成后,单独把最小值压入原栈顶即可。
import java.util.Scanner;
import java.util.Stack;

public class StackTest {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        Stack<Integer> stack1 = new Stack<>();
        for (int i = 0; i < 5; i++) {
            stack1.push(input.nextInt());
        }

        System.out.println("------------------");
        findSmallest(stack1);
        for (int i = 0; i < 5; i++) {
            System.out.println(stack1.pop());
        }
    }

    public static void findSmallest(Stack<Integer> stack1) {
        Stack<Integer> stack2 = new Stack<>();
        Integer min = stack1.peek();
        int stackSize = stack1.size();
        // 第一次遍历:所有元素移到临时栈,同步记录最小值
        for (int i = 0; i < stackSize; i++) {
            Integer current = stack1.pop();
            if (current < min) {
                min = current;
            }
            stack2.push(current);
        }
        boolean minFound = false;
        // 第二次遍历:非最小值元素移回原栈,遇到最小值跳过压入
        for (int i = 0; i < stackSize; i++) {
            Integer current = stack2.pop();
            if (!minFound && current.equals(min)) {
                minFound = true;
                continue;
            }
            stack1.push(current);
        }
        // 最小值压入栈顶
        stack1.push(min);
    }
}
效果验证

输入序列1 2 3 4 5按顺序压入栈后,调用修复后的方法,栈的输出序列为[2, 3, 4, 5, 1],符合预期结果;执行pop打印时输出顺序为1、5、4、3、2,第一个弹出的就是栈顶的最小元素1,其余元素相对顺序保持不变。

内容的提问来源于stack exchange,提问作者ojcoding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 05:24:15