3 4 4 利用棧將遞迴轉換成非遞迴的方法

2022-06-26 16:09:15 字數 961 閱讀 9245

在函式執行時系統需要設立乙個「遞迴工作棧」儲存第一層遞迴所需的資訊,此工作棧是遞迴函式執行的輔助空間,所以可以看出,遞迴程式在執行時需要系統提供隱式棧這種資料結構來實現,對於一般的遞迴過程,仿照遞迴演算法執行過程中遞迴工作棧的狀態變化可直接寫出相應的非遞迴演算法。這種利用棧消除遞迴過程的步驟如下。

(1)設定乙個工作棧存放遞迴工作記錄(包括實參、返回位址及區域性變數等)

(2)進入非遞迴呼叫入口(即被呼叫程式開始處)將呼叫程式傳來的實在引數和返回位址入棧(遞迴程式不可以作為主程式,因而可認為初始是被某個呼叫程式呼叫)。

(4)遞迴結束條件滿足,將到達遞迴出口的給定常數作為當前的函式值。

通過以上步驟就可以將遞迴演算法改寫成非遞迴演算法。

最終要的是每一層遞迴資訊構成乙個工作記錄,其中包括所有的實參,所有的區域性變數,以及上一層的返回位址。每進入一層遞迴就產生乙個新的工作記錄壓入棧頂。沒退出一層遞迴就從棧頂彈出乙個工作記錄。

改寫後的演算法具有如下特點:結構不清晰,可讀性差,有的還需要經過一系列優化。【案例見《資料結構》嚴蔚敏 c語言 第二版 5.5.1節中二叉樹中序遍歷的非遞迴演算法】。

遞迴演算法的特點:結構清晰,程式易讀,而且其正確性容易證明。

而且遞迴演算法中將遞迴工作棧交給了系統來管理,而非遞迴則把編制程式的記憶體交給了程式設計師管理。

【課本講解】

規範化的遞迴轉換成非遞迴

遞迴函式被呼叫時,系統需要乙個執行棧。系統的執行棧要儲存函式的返回位址,儲存呼叫函式的區域性變數,每一層遞迴呼叫所需儲存的資訊構成執行棧的乙個工作記錄,在沒進入下一層遞迴呼叫是,系統就會建立乙個新的工作記錄,並把這個工作記錄進棧成為執行棧新的棧頂,每返回一層遞迴呼叫,就退棧乙個工作記錄,因棧頂的工作...

資料結構 用棧來將遞迴轉換成迴圈

為什麼將遞迴轉換成迴圈需要用到棧?遞迴其實是在每次呼叫自己來進入新的狀態,直到最後一次的狀態能夠滿足遞迴的結束條件,然後返回到上次的狀態。我們都知道棧有著後進先出的特性,那這樣是不是就可以理解為遞迴每呼叫一層就壓入棧,直到最後滿足遞迴結束條件,再一層層彈出棧,那麼用棧來將遞迴改為迴圈,就可以理解了。...

用棧將遞迴轉化為非遞迴

在競賽中如果系統棧很小的話,過深的遞迴會讓棧溢位,這個時候我們就要自己手寫棧,將遞迴轉化成手工棧。方法其實也很簡單。基本思路上,我們就是用棧不斷的pop,push。但是何時push,何時pop呢?在 演算法導論 上對深度優先遍歷樹的講解中,在深度遍歷中,會對每個節點進行染色,白色為沒有被訪問過 灰色...