棧Stack——遞迴替身?

Ashe|||^_^發表於2024-09-12

棧Stack——遞迴替身?

棧Stack——遞迴替身?

對於Stack這個集合類,由類繼承關係可知是Vector的子類,根據push入棧方法跟蹤程式碼,可知Vector是一個執行緒安全的類(高併發場景下使用,那可能不是一個好的選擇)

棧Stack——遞迴替身?

看到這裡,顯然可以得知Stack入棧出棧的大致原理,就是Vector的elementData物件陣列,用來儲存資料,入棧時依次存放,出棧時倒序從陣列中取出即可

棧Stack——遞迴替身?

單向連結串列反轉列印這樣的場景中,我們可以很自然地想到使用遞迴來實現,相比遞迴我們可以使用Stack類依次將單向連結串列的Node節點存放至Stack的物件陣列中,然後反向出棧取出即可。

    public void reversePrint(Node node) {
        Stack<Node> stack = new Stack<>();
        while (node != null) {
            stack.push(node);
            node = node.next;
        }
        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
    }

    public void recursion(Node node) {
        if (node.next != null) {
            recursion(node.next);
        }
        System.out.println(node);
    }

顯然,在連結串列中節點元素較多的場景下,使用Stack的方案明顯所需的memory更少。我們可以根據這個簡單的示例,在遞迴場景下優先考慮Stack方案的可能性~(使用了資料結構來最佳化:方法呼叫所需要的記憶體空間)

當程式執行一個方法時,它會在呼叫棧上建立一個新的棧幀(Stack Frame)。這個棧幀包含了執行該方法所需的所有資訊。當方法執行完畢並準備返回時,它的棧幀會從呼叫棧中彈出,控制權返回給呼叫者。

對於遞迴方法,每次遞迴呼叫都會建立一個新的棧幀,並將其推入呼叫棧中。如果遞迴呼叫過深,即呼叫棧中的棧幀數量超過了系統或JVM(Java虛擬機器)等環境為呼叫棧分配的記憶體限制,就會發生棧溢位錯誤(StackOverflowError)。

相關文章