1. 程式人生 > >佇列實現棧,兩個佇列實現一個棧方法詳解(含實現程式碼)

佇列實現棧,兩個佇列實現一個棧方法詳解(含實現程式碼)

本節介紹一下如何用兩個佇列實現棧。

棧的主要操作就是入棧和出棧,其特點就是後進先出。我們先將兩個佇列分別定義為 queue1 與 queue2。

方案 1

入棧和出棧,都在 queue1 中完成,而 queue2 作為中轉空間。
  • 入棧:直接入 queue1 即可。
  • 出棧:把 queue1 中除最後一個元素外的所有元素都移動到 queue2 中,再將 queue1 中的元素出隊,此時即出棧;接著將 queue2 中的所有元素移動到 queue1 中。

具體操作如圖 1 和圖 2 所示。


圖 1 入棧操作示例


圖 2 出棧操作示例
該操作過程與用棧實現佇列的方案 1 一樣,都是把第 2 個結構當作一箇中轉站,然後將資料來回倒。接下來看一個更優一點的方案。

方案 2

從方案 1 的操作方式中,我們可以看出其劣勢,即在出棧時要把 queue2 中的元素移動到 queue1 中。在兩個佇列之間能否不用每次先出棧再把元素移動回去?當然可以。下面是入棧、出棧的具體操作描述。
  • 入棧:兩個佇列哪個不為空,就把元素入隊到哪個佇列中;如果都為空,則任選一個佇列入隊,假設這個佇列就是 queue1。
  • 出棧:把不為空的佇列中除最後一個元素外的所有元素移動到另一個佇列中,然後出隊最後一個元素。

這樣方案 2 就更簡單了,省去了方案 1 中最後一步的轉回操作。

下面是實現程式碼:
package me.irfen.algorithm.ch02.extend;
import me.irfen.algorithm.ch02.ArrayQueue;
public class Queue2Stack {
    private ArrayQueue queue1;
    private ArrayQueue queue2;
    private int maxLength;
   
    public Queue2Stack(int capacity) {
        maxLength = capacity;
        queue1 = new ArrayQueue(capacity);
        queue2 = new ArrayQueue(capacity);
    }
   
    /**
     * 入棧
     * @param item
     * @return 入棧結果
     */
    public boolean push(int item) {
        if (size() == maxLength) {
            return false;
        }
        if (queue2.isEmpty()) {
            queue1.put(item);
        } else {
            queue2.put(item);
        }
        return true;
    }
   
    /**
     * 出棧
     * @return
     */
    public Object pop() {
        if (size() == 0) {
            throw new IndexOutOfBoundsException("棧裡已經空啦");
        } else {
            if (queue2.isEmpty()) {
                while (queue1.size() > 1) {
                    queue2.put(queue1.poll());
                }
                return queue1.poll();
            } else {
                while (queue2.size() > 1) {
                    queue1.put(queue2.poll());
                }
                return queue2.poll();
            }
        }
    }
   
    public int size() {
        return queue1.size() + queue2.size();
    }
}
測試程式碼如下:
package me.irfen.algorithm.ch02.extend;
public class Queue2StackTest {
    public static void main(String[] args) {
        Queue2Stack stack = new Queue2Stack(5);
        stack.push(1);
        stack.push(2);
        System.out.println(stack.pop()); // 2
        stack.push(3);
        stack.push(4);
        System.out.println(stack.pop()); // 4
        System.out.println(stack.pop()); // 3
    }
}