循環與遞歸的區別

循環(迭代)與遞歸的區別

 

簡單來說: 

遞歸: 易於理解, 速度慢, 存儲空間大,

循環: 不易理解, 速度快, 存儲空間小. 

文章出處: http://blog.sina.com.cn/s/blog_62b1508e0100hcyx.html


1。遞歸算法與迭代算法的設計思路區別在於:函數或算法是否具備收斂性,當且僅當一個算法存在預期的收斂效果時,採用遞歸算法纔是可行的,否則,就不能使用遞歸算法。

當然,從理論上說,所有的遞歸函數都可以轉換爲迭代函數,反之亦然,然而代價通常都是比較高的。但從算法結構來說,遞歸聲明的結構並不總能夠轉換爲迭代結構,原因在於結構的引申本身屬於遞歸的概念,用迭代的方法在設計初期根本無法實現,這就像動多態的東西並不總是可以用靜多態的方法實現一樣。這也是爲什麼在結構設計時,通常採用遞歸的方式而不是採用迭代的方式的原因,一個極典型的例子類似於鏈表,使用遞歸定義及其簡單,但對於內存定義(數組方式)其定義及調用處理說明就變得很晦澀,尤其是在遇到環鏈、圖、網格等問題時,使用迭代方式從描述到實現上都變得很不現實。

 

2。遞歸其實是方便了程序員難爲了機器。它只要得到數學公式就能很方便的寫出程序。優點就是易理解,容易編程。但遞歸是用棧機制實現的(c++),每深入一層,都要佔去一塊棧數據區域,對嵌套層數深的一些算法,遞歸會力不從心,空間上會以內存崩潰而告終,而且遞歸也帶來了大量的函數調用,這也有許多額外的時間開銷。所以在深度大時,它的時空性就不好了。

循環其缺點就是不容易理解,編寫複雜問題時困難。優點是效率高。運行時間只因循環次數增加而增加,沒什麼額外開銷。空間上沒有什麼增加。

 

3。局部變量佔用的內存是一次性的,也就是O(1)的空間複雜度,而對於遞歸(不考慮尾遞歸優化的情況),每次函數調用都要壓棧,那麼空間複雜度是O(n),和遞歸次數呈線性關係。

 

4。遞歸程序改用循環實現的話,一般都是要自己維護一個棧的,以便狀態的回溯。如果某個遞歸程序改用循環的時候根本就不需要維護棧,那其實這個遞歸程序這樣寫只是意義明顯一些,不一定要寫成遞歸形式。但很多遞歸程序就是爲了利用函數自身在系統棧上的auto變量記錄狀態,以便回溯。

原理上講,所有遞歸都是可以消除的,代價就是可能自己要維護一個棧。而且我個人認爲,很多情況下用遞歸還是必要的,它往往能把複雜問題分解成更爲簡單的步驟,而且很能反映問題的本質。

 

 

首先,遞歸和遞推又一定的相似性(當然了,不然怎麼會提出這個問題?)

這兩個問題都可以描述爲以下形式:

f(n)=g(f(n-1)f(0))

這是二者的共同特點。

 

不同點:

1,從程序上看,遞歸表現爲自己調用自己,遞推則沒有這樣的形式。

2,遞歸是從問題的最終目標出發,逐漸將複雜問題化爲簡單問題,最終求得問題

是逆向的。遞推是從簡單問題出發,一步步的向前發展,最終求得問題。是正向的。

3,遞歸中,問題的n要求是計算之前就知道的,而遞推可以在計算中確定,不要求計算前就知道n

4,一般來說,遞推的效率高於遞歸(當然是遞推可以計算的情況下)

 

由於一切遞歸問題都可以轉化爲循環求解,因此我們可以定義廣義遞歸:

 

如果轉化爲循環後,需要自己維護堆棧,則仍稱爲是遞歸的。

 

在這個定義下,有些問題適用於用遞歸求解,如梵塔問題有些問題適用於用遞推來做,如求滿足N!>M條件時最小的N。有些問題二者都可以,如給定N時的階乘問題。至於可讀性,與問題有關,不能一概而論。

 

遞歸其實就是利用系統堆棧,實現函數自身調用,或者是相互調用的過程。在通往邊界的過程中,都會把單步地址保存下來,知道等出邊界,再按照先進後出的進行運算,這正如我們裝木桶一樣,每一次都只能把東西方在最上面,而取得時候,先放進取的反而最後取出。遞歸的數據傳送也類似。但是遞歸不能無限的進行下去,必須在一定條件下停止自身調用,因此它的邊界值應是明確的。就向我們裝木桶一樣,我們不能總是無限制的往裏裝,必須在一定的時候把東取出來。比較簡單的遞歸過程是階乘函數,你可以去看一下。但是遞歸的運算方法,往往決定了它的效率很低,因爲數據要不斷的進棧出棧。這時遞推便表現出它的作用了,所謂遞推,就是免除了數據進出棧的過程。也就是說,不需要函數不斷的向邊界值靠攏,而直接從邊界出發,直到求出函數值。比如,階乘函數中,遞歸的數據流動過程如下:

 

f(3){f(i)=f(i-1)*i}-->f(2)-->f(1)-->f(0){f(0)=1}-->f(1)-->f(2)--f(3){f(3)=6}

 

而遞推如下:

 

f(0)-->f(1)-->f(2)-->f(3)

 

由此可見,遞推的效率要高一些,在可能的情況下應儘量使用遞推。但是遞歸作爲比較基礎的算法,它的作用不能忽視。所以,在把握這兩種算法的時候應該特別注意。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章