惡補基礎知識:Java 棧與佇列詳解

南国以南i發表於2024-08-15

@

目錄
  • 前言
  • 簡介
      • Java實現棧的示例程式碼:
      • 棧的主要應用場景包括:
    • 佇列
      • Java實現佇列的示例程式碼:
      • LinkedList中的add方法和offer方法的區別
      • 佇列主要應用場景:
  • 總結


前言

請各大網友尊重本人原創知識分享,謹記本人部落格:南國以南i


提示:以下是本篇文章正文內容,下面案例可供參考

簡介

使用Java實現 棧(Stack)佇列(Queue) 的操作是很常見的任務。棧和佇列是兩種不同的資料結構,它們分別具有特定的操作和行為。

棧是一種 後進先出(LIFO, Last In First Out) 的資料結構。它只允許在棧頂進行新增(push)或刪除(pop)元素的操作。類似於羽毛球球桶一樣最開始放進去的球需要最後拿出來

Java實現棧的示例程式碼:

public static void query() {
        Queue<Integer> queue = new LinkedList<>();
        // 入隊
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);

        // 檢視隊首元素
        System.out.println("隊首元素: " + queue.peek()); // 不移除隊首元素

        // 出隊
        while (!queue.isEmpty()) {
            System.out.println("出隊元素: " + queue.poll());
        }
    }


    public static void stack() {
        //1、建立棧:使用Stack類(儘管Stack是遺留類,更推薦使用Deque介面的實現如ArrayDeque)或Deque介面(及其實現類如ArrayDeque)來實現棧。
        //Stack<Integer> stack = new Stack<Integer>();
        Deque<Integer> stack = new ArrayDeque<>();

        //2、入棧將元素新增到棧頂
        stack.push(1);
        stack.push(2);
        stack.push(3);

        //3、出棧(Pop):從棧頂移除元素,並返回被移除的元素。Stack類提供了pop()方法用於出棧操作
        int element = stack.pop(); // 返回並移除棧頂元素
        System.out.println(element); // 輸出:3


        // 4、訪問棧頂元素(Peek):獲取棧頂元素,但不對棧進行修改。Stack類提供了peek()方法用於訪問棧頂元素
        int outElement = stack.peek(); // 返回棧頂元素但不移除
        System.out.println("棧頂元素: " + outElement); // 輸出:3

        // 5、迴圈出棧
        while (!stack.isEmpty()) {
            System.out.println("出棧元素: " + stack.pop());
        }
        
        /*輸出:
        棧頂元素: 3
        出棧元素: 3
        出棧元素: 2
        出棧元素: 1*/
    }

棧的主要應用場景包括:

  1. 函式呼叫棧:
    在程式語言中,函式呼叫是透過棧來實現的。當函式被呼叫時,它的區域性變數、引數和返回地址等資訊會被壓入棧中。當函式執行完畢時,這些資訊會從棧中彈出,控制權返回給呼叫者。

  2. 瀏覽器的前進後退:
    瀏覽器的歷史記錄通常使用棧來管理。當我們瀏覽網頁時,每個訪問的頁面都會被壓入棧中;當我們點選“後退”時,頁面會從棧中彈出,返回到上一個頁面。

  3. 括號匹配:
    在解析或編譯程式碼時,檢查圓括號、花括號等是否匹配是一個常見問題。棧可以用來解決這個問題,每當遇到一個左括號時,就將其壓入棧中;每遇到一個右括號時,就檢查棧頂元素是否與之匹配,如果匹配則彈出棧頂元素,否則報錯。

  4. 撤銷操作:
    在許多編輯器或圖形介面中,使用者可以透過撤銷操作回到之前的狀態。撤銷操作通常使用棧來實現,每次操作都會被壓入棧中,當使用者執行撤銷操作時,棧頂的操作會被彈出並應用於當前狀態。

佇列

佇列是一種 先進先出(FIFO, First In First Out) 的資料結構。它只允許在隊尾新增元素(enqueue)和在隊首刪除元素(dequeue)類似於排隊的過程

Java實現佇列的示例程式碼:

public static void queue() {
        // 1、建立佇列:我們可以使用Java的集合類LinkedList來實現佇列的操作。
        Queue<Integer> queue = new LinkedList<>();
        // 2、入隊(Enqueue):將元素新增到隊尾。LinkedList類提供了offer()方法用於入隊操作。
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);

        //3、出隊(Dequeue):從隊頭移除元素,並返回被移除的元素。LinkedList類提供了poll()方法用於出隊操作。
        int element = queue.poll(); // 返回並移除隊頭元素
        System.out.println(element); // 輸出:1

        // 4、訪問隊頭元素(Peek):獲取隊頭元素,但不對佇列進行修改。LinkedList類提供了peek()方法用於訪問隊頭元素。
        System.out.println("隊首元素: " + queue.peek()); // 不移除隊首元素

        // 5、迴圈出隊
        while (!queue.isEmpty()) {
            System.out.println("出隊元素: " + queue.poll());
        }

        /*輸出:
        隊首元素: 1
        出隊元素: 1
        出隊元素: 2
        出隊元素: 3*/
    }

LinkedList中的add方法和offer方法的區別

add方法:‌ add方法屬於Collection介面,‌它試圖將指定的元素新增到列表中。‌如果新增成功,‌它返回true;‌如果因為某些原因(‌如容量限制)‌新增失敗,‌它會丟擲IllegalStateException異常。‌在LinkedList中,‌當佇列為空時,‌使用add方法可能會因為違反容量限制而報錯。‌此外,‌當將LinkedList視為列表使用時,‌通常採用add方法來壓入物件。‌

offer方法:‌ offer方法屬於Deque介面(‌雙端佇列)‌,‌它試圖將指定的元素插入到佇列中。‌如果插入成功,‌它返回true;‌如果因為空間限制無法新增元素,‌則返回false。‌與add方法不同,‌offer方法不會丟擲異常,‌而是透過返回值來指示操作是否成功。‌在有容量限制的佇列中,‌offer方法優於add方法,‌因為它透過返回false來處理空間不足的情況,‌而不是丟擲異常,‌這種方式更加高效。‌

總結來說,‌add方法和offer方法的主要區別在於它們的返回值和異常處理方式。‌add方法可能會因為違反容量限制而丟擲異常,‌而offer方法則透過返回值來指示操作是否成功,‌避免了異常處理開銷。‌

佇列主要應用場景:

  1. 任務排程:
    在多工處理系統中,任務通常被儲存在一個佇列中。系統按照任務進入佇列的順序來執行它們,實現了公平的排程。

  2. 訊息傳遞:
    在程序間通訊或網路程式設計中,訊息通常被儲存在一個佇列中。傳送者將訊息傳送到佇列的尾部,接收者從佇列的頭部取出訊息進行處理。

  3. 頁面請求處理:
    在Web伺服器中,多個使用者請求可能同時到達。伺服器可以將這些請求儲存在一個佇列中,然後按照請求到達的順序進行處理。

  4. 廣度優先搜尋(BFS):
    在圖的遍歷演算法中,廣度優先搜尋使用佇列來儲存待訪問的節點。演算法開始時,將起始節點加入佇列。然後,演算法迴圈進行,每次從佇列中取出一個節點進行訪問,並將其未被訪問的鄰接節點加入佇列。

總結

瞭解棧和佇列的應用場景有助於我們根據實際需求選擇合適的資料結構,從而更高效地解決問題。


我是南國以南i記錄點滴每天成長一點點,學習是永無止境的!轉載請附原文連結!!!

相關文章