数据结构:用双栈实现一个队列

发布于:2024-10-11 ⋅ 阅读:(12) ⋅ 点赞:(0)

要用两个栈实现一个队列,可以利用“栈”的后进先出 (LIFO) 特性来模拟“队列”的先进先出 (FIFO) 操作。具体做法是使用两个栈:一个作为入栈栈,另一个作为出栈栈。

算法步骤

  1. 入队操作(enqueue): 将元素压入“入栈栈”。
  2. 出队操作(dequeue): 如果“出栈栈”为空,就将“入栈栈”中的所有元素逐个弹出并压入“出栈栈”,然后从“出栈栈”弹出栈顶元素。否则,直接从“出栈栈”弹出栈顶元素。

这种方法确保了队列的先进先出(FIFO)特性。

Java 实现

import java.util.Stack;

public class QueueWithTwoStacks<T> {
    // 入栈栈,用于接收新元素
    private Stack<T> stackIn;
    // 出栈栈,用于弹出元素
    private Stack<T> stackOut;

    // 构造函数
    public QueueWithTwoStacks() {
        stackIn = new Stack<>();
        stackOut = new Stack<>();
    }

    // 入队操作,将元素压入入栈栈
    public void enqueue(T item) {
        stackIn.push(item);
    }

    // 出队操作,从出栈栈弹出元素
    public T dequeue() {
        // 如果出栈栈为空,则将入栈栈的元素倒入出栈栈
        if (stackOut.isEmpty()) {
            if (stackIn.isEmpty()) {
                throw new RuntimeException("Queue is empty");
            }
            while (!stackIn.isEmpty()) {
                stackOut.push(stackIn.pop());
            }
        }
        return stackOut.pop();
    }

    // 获取队列头部元素,但不出队
    public T peek() {
        if (stackOut.isEmpty()) {
            if (stackIn.isEmpty()) {
                throw new RuntimeException("Queue is empty");
            }
            while (!stackIn.isEmpty()) {
                stackOut.push(stackIn.pop());
            }
        }
        return stackOut.peek();
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return stackIn.isEmpty() && stackOut.isEmpty();
    }

    public static void main(String[] args) {
        QueueWithTwoStacks<Integer> queue = new QueueWithTwoStacks<>();

        queue.enqueue(1);
        queue.enqueue(2);
        queue.enqueue(3);

        System.out.println(queue.dequeue()); // 输出 1
        System.out.println(queue.peek());    // 输出 2
        System.out.println(queue.dequeue()); // 输出 2

        queue.enqueue(4);
        System.out.println(queue.dequeue()); // 输出 3
        System.out.println(queue.dequeue()); // 输出 4
    }
}

解释:

  1. 两个栈: stackIn 是用于入队的栈,stackOut 是用于出队的栈。
  2. 入队操作: 元素被直接压入 stackIn,这保证了入队的顺序。
  3. 出队操作: 当 stackOut 为空时,将 stackIn 中的所有元素倒入 stackOut,以便反转元素顺序,使其符合队列的 FIFO 特性。

这样,你就可以使用两个栈来实现一个队列,且满足队列的基本功能。