將遞歸算法改為非遞歸算法


1.遞歸與非遞歸的區別:

遞歸的代碼量比非遞歸的代碼量少,因為非遞歸需要額外的變量記錄當前所處的位置信息,以及額外的控制語句。而遞歸所使用的方式是函數調用,這是非常自然的棧結構,不需要記錄位置信息,不需要添加控制語句,這些工作都由函數調用的特性解決了。

遞歸的執行效率比非遞歸的執行效率低,因為遞歸的實質是函數調用,而函數調用必然要進行線程棧空間的分配,記錄每一次函數調用前的狀態等工作,開銷是比較大的。而非遞歸則不需要進行這些工作。

遞歸與非遞歸調用最主要區別就是在函數調用上。在計算機的工作方式中,函數調用是以棧結構來實現的,最早調用的函數處於棧底,最晚調用的函數處於棧頂,棧中存放的是每個函數中的局部變量等信息,當函數調用返回時該函數相關的信息就會從棧中彈出。

由此可以看出,遞歸每深入一層,棧的深度也會加一,而且當每一層的遞歸調用結束,都會自動返回上一層的遞歸中,因此不需要額外的變量記錄當前所處的遞歸位置,也不需要while、if等控制語句進入或返回上一層或下一層遞歸。因此代碼量比非遞歸的少。

但正因為函數調用要在棧中進行各種操作,例如分配新的空間,保存當前函數調用的信息,為新的函數調用初始化等,效率比較低下。所以遞歸的效率比非遞歸的低。

2.轉化

遞歸是指某個函數或過程直接或間接的調用自身。一般地一個遞歸包括遞歸出口和遞歸體兩部分,遞歸出口確定遞歸到何時結束,而遞歸體確定遞歸求解時的遞推關系。遞歸算法有兩個基本特征:一是遞歸算法是一種分而治之的、把復雜問題分解為簡單問題的求解問題方法,對於求解某些復雜問題,遞歸算法分析問題的方法是有效地;而是遞歸算法的時間、控件效率通常比較差。因此對解決某些問題時,我們希望用遞歸算法分析問題,用非遞歸算法解決問題,這就需要把遞歸算法轉換為非遞歸算法。

把遞歸算法轉化為非遞歸算法有如下三種基本方法:

(1). 通過分析,跳過分解過程,直接用循環結構的算法實現求解過程。

(2). 自己用棧模擬系統的運行時棧,通過分析只保存必須保存的信息,從而用非遞歸算法替代遞歸算法。

(3). 利用棧保存參數,由於棧的后進先出特性吻合遞歸算法的執行過程,因而可以用非遞歸算法替代遞歸算法。


3.分析

遞歸深度小於3的,優化結果不明顯。大於3的,優化后差距能達到70%以上。

目前QQ超市1店5口,以后2店3口之后的圖,遞歸深度甚至達到了60層。

經過測試發現路徑算出速度低了10多倍。非遞歸的轉換勢在必行!!

要回去從頭學一下二叉樹了……


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM