1.遞歸與非遞歸的區別:
遞歸的代碼量比非遞歸的代碼量少,因為非遞歸需要額外的變量記錄當前所處的位置信息,以及額外的控制語句。而遞歸所使用的方式是函數調用,這是非常自然的棧結構,不需要記錄位置信息,不需要添加控制語句,這些工作都由函數調用的特性解決了。
遞歸的執行效率比非遞歸的執行效率低,因為遞歸的實質是函數調用,而函數調用必然要進行線程棧空間的分配,記錄每一次函數調用前的狀態等工作,開銷是比較大的。而非遞歸則不需要進行這些工作。
遞歸與非遞歸調用最主要區別就是在函數調用上。在計算機的工作方式中,函數調用是以棧結構來實現的,最早調用的函數處於棧底,最晚調用的函數處於棧頂,棧中存放的是每個函數中的局部變量等信息,當函數調用返回時該函數相關的信息就會從棧中彈出。
由此可以看出,遞歸每深入一層,棧的深度也會加一,而且當每一層的遞歸調用結束,都會自動返回上一層的遞歸中,因此不需要額外的變量記錄當前所處的遞歸位置,也不需要while、if等控制語句進入或返回上一層或下一層遞歸。因此代碼量比非遞歸的少。
但正因為函數調用要在棧中進行各種操作,例如分配新的空間,保存當前函數調用的信息,為新的函數調用初始化等,效率比較低下。所以遞歸的效率比非遞歸的低。
2.轉化
遞歸是指某個函數或過程直接或間接的調用自身。一般地一個遞歸包括遞歸出口和遞歸體兩部分,遞歸出口確定遞歸到何時結束,而遞歸體確定遞歸求解時的遞推關系。遞歸算法有兩個基本特征:一是遞歸算法是一種分而治之的、把復雜問題分解為簡單問題的求解問題方法,對於求解某些復雜問題,遞歸算法分析問題的方法是有效地;而是遞歸算法的時間、控件效率通常比較差。因此對解決某些問題時,我們希望用遞歸算法分析問題,用非遞歸算法解決問題,這就需要把遞歸算法轉換為非遞歸算法。
把遞歸算法轉化為非遞歸算法有如下三種基本方法:
(1). 通過分析,跳過分解過程,直接用循環結構的算法實現求解過程。
(2). 自己用棧模擬系統的運行時棧,通過分析只保存必須保存的信息,從而用非遞歸算法替代遞歸算法。
(3). 利用棧保存參數,由於棧的后進先出特性吻合遞歸算法的執行過程,因而可以用非遞歸算法替代遞歸算法。
3.分析
遞歸深度小於3的,優化結果不明顯。大於3的,優化后差距能達到70%以上。
目前QQ超市1店5口,以后2店3口之后的圖,遞歸深度甚至達到了60層。
經過測試發現路徑算出速度低了10多倍。非遞歸的轉換勢在必行!!
要回去從頭學一下二叉樹了……