首頁 > 軟體

Java 棧和佇列的相互轉換詳解

2022-02-14 16:00:26

棧和佇列的本質是相同的,都只能線上性表的一端進行插入和刪除。因此,棧和佇列可以相互轉換。

用棧實現佇列—力扣232題

題目要求:僅使用兩個棧實現先入先出佇列。佇列應當支援一般佇列支援的所有操作

使用雙棧來實現佇列,我們就可以讓一個棧儲存具體元素,另一個棧做輔助 

上圖可以看到,新元素進棧時,要確保該棧為空。進入棧的元素按順序存到輔助棧中,等新元素進入棧之後,再將輔助棧中的元素按順序出到該棧中。這樣操作之後,棧中元素存放的順序就和佇列的一樣啦

程式碼實現:

 
//雙棧模擬佇列
public class MyQueue{
    //實際儲存元素的棧
    private Stack<Integer> s1 = new Stack<>();
    //輔助棧
    private Stack<Integer> s2 = new Stack<>();
 
    public MyQueue() {
 
    }
 
    //將元素 x 推到佇列的末尾
    public void push(int x) {
        if (s1.empty()){//棧為空,直接放入x
            s1.push(x);
        }else {
            //此時不為空
            //先把s1所有元素彈出放入s2
            while (!s1.empty()){
                s2.push(s1.pop());//s2放入的值就是s2彈出的值
                //以下兩句和上一句相同
//                int val = s1.pop();
//                s2.push(val);
            }
            //將新元素直接放入s1,此時新元素就處在s1的棧頂
            s1.push(x);
            //再次將s2的所有值依次彈出放入s1
            while (!s2.empty()){
                s1.push(s2.pop());
            }
        }
 
    }
 
    //從佇列的開頭移除並返回元素
    public int pop() {
       return s1.pop();
    }
 
    //返回佇列開頭的元素
    public int peek() {
        return s1.peek();
    }
 
    //判斷佇列是否為空
    public boolean empty() {
        return s1.empty();
    }
}

用佇列實現棧—力扣225題 

題目要求:僅使用兩個佇列實現一個後入先出(LIFO)的棧,並支援普通棧的全部四種操作

1. 雙佇列實現棧

使用雙佇列實現棧, q1是儲存元素的佇列,保證q2新增元素之後永遠為空佇列(新元素直接入q2),保證新元素處在隊首。這樣的話,新元素入隊之後,另外一個佇列的元素依次出隊然後入隊,這樣就實現了一個棧。

程式碼實現:

public class MyStack {
    //q1是儲存元素的佇列
    private Queue<Integer> q1 = new LinkedList<>();
    //q2是輔助佇列
    //新增元素後保證q2永遠為空
    private Queue<Integer> q2 = new LinkedList<>();
    public MyStack () {
 
    }
 
    //將元素 x 壓入棧頂
    public void push(int x) {
        //新入隊元素直接入q2,成為q2隊首
        q2.offer(x);
        //將q1中的所有元素依次出隊,入q2
        while (!q1.isEmpty()){
            q2.offer(q1.poll());
        }
 
        //q1為空,q2為儲存元素的佇列,互換參照指向
        //互換之後,q1任然是儲存元素的佇列,q2為空
        Queue<Integer> temp = q1;
        q1 = q2;
        q2 = temp;
    }
 
    // 移除並返回棧頂元素
    public int pop() {
        return q1.poll();
    }
 
    //返回棧頂元素
    public int top() {
        return q1.peek();
    }
 
    //判斷棧是否為空
    public boolean empty() {
        return q1.isEmpty();
    }
}
 

2.一個佇列實現棧

先將元素入隊,再將之前的元素依次出隊再入隊即可!也就是說,保證新元素在隊首

程式碼實現:

public class MyStack {
    private Queue<Integer> queue = new LinkedList<>();
    public MyStack() {
    }
 
    public void push(int x) {
        //記錄之前元素的個數
        int size = queue.size();
        //將新元素入隊
        queue.offer(x);
        //將之前的元素依次出隊再入隊,新元素就在隊首位置
        for (int i = 0; i < size; i++) {
            queue.offer(queue.poll());
        }
 
    }
 
    public int pop() {
        return queue.poll();
    }
 
    public int top() {
        return queue.peek();
    }
 
    public boolean empty() {
        return queue.isEmpty();
    }
}

這幾個例題實踐目的是更加熟悉的掌握和了解棧和佇列,實際應用中是不推薦的哦。

到此這篇關於Java 棧和佇列的相互轉換詳解的文章就介紹到這了,更多相關Java 棧和佇列 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com