遞迴與迭代的聯絡以及優缺點(以c++為例)

浪裡飛發表於2018-11-13

 1.遞迴的定義:

程式直接或間接的呼叫自身的方法。

遞迴演算法的特點:
(1) 遞迴就是在過程或函式裡呼叫自身。
(2) 在使用遞迴策略時,必須有一個明確的遞迴結束條件,稱為遞迴出口。
(3) 遞迴演算法解題通常顯得很簡潔,但遞迴演算法解題的執行效率較低。所以一般不提倡用遞迴演算法設計程式。
(4) 在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存。遞迴次數過多容易造成棧溢位等。所以一般不提倡用遞迴演算法設計程式。

遞迴演算法的程式碼,可以分成兩個部分:遞迴部分包括遞迴程式碼的主體和遞迴出口(需要滿足的輸出條件)。把整體運算轉換為分步運算。

案例:漢諾塔

這個例子可以用遞迴演算法實現。

ABC分別是123柱子,程式碼思路大概是這樣的

把N-1層的環子先通過C移到B,最後再把第N層的最大的環子移到C,這個時候就剩下一個N-1層的新“塔”,那麼我們把他看成一個新的“塔”把B柱看成之前的A柱,通過C柱把(N-1)-1層移到A柱,再把第N-1層的最大(原本第二大)的環子放到C,如此迴圈到最後的N=1 。
實現方法:

 1 #include<iostream>
 2 using namespace std;
 3 void hanoi(int n,char a,char b,char c)
 4 {
 5   if(n==1)
 6   cout<<n<<" "<<a<<" "<<c<<endl;
 7   else
 8   {
 9     hanoi(n-1,a,c,b);
10     cout<<n<<" "<<a<<" "<<c<<endl;
11     hanoi(n-1,b,a,c);
12   }
13 }
14 int main()
15 {
16   int n;
17   cout<<"輸入正整數:"<<endl;
18   cin>>n;
19   cout<<"結果為"<<endl;
20   hanoi(n,'A','B','C');
21 
22 
23   return 0;
24 } 

2.分析:

從演算法結構來說,遞迴宣告的結構並不總能夠轉換為迭代結構,原因在於結構的引申本身屬於遞迴的概念,用迭代的方法在設計初期根本無法實現,這就像動多型的東西並不總是可以用靜多型的方法實現一樣。這也是為什麼在結構設計時,通常採用遞迴的方式而不是採用迭代的方式的原因,一個極典型的例子類似於連結串列,使用遞迴定義及其簡單,但對於記憶體定義(陣列方式)其定義及呼叫處理說明就變得很晦澀,尤其是在遇到環鏈、圖、網格等問題時,使用迭代方式從描述到實現上都變得不現實。因而可以從實際上說,所有的迭代可以轉換為遞迴,但遞迴不一定可以轉換為迭代。採用遞迴演算法需要的前提條件是,當且僅當一個存在預期的收斂時,才可採用遞迴演算法,否則,就不能使用遞迴演算法。

遞迴的優點:

1)大問題化為小問題,可以極大的減少程式碼量;

2)用有限的語句來定義物件的無限集合.;

3)程式碼更簡潔清晰,可讀性更好

遞迴的缺點

1)遞迴呼叫函式,浪費空間;

2)遞迴太深容易造成堆疊的溢位;

 

迭代的優點:

1)迭代效率高,執行時間只因迴圈次數增加而增加;

2)沒什麼額外開銷,空間上也沒有什麼增加,

迭代的缺點:

1) 不容易理解;

2) 程式碼不如遞迴簡潔;

3) 編寫複雜問題時困難。

3.兩者之間的關係

1) 遞迴中一定有迭代,但是迭代中不一定有遞迴,大部分可以相互轉換。

2) 能用迭代的不用遞迴,遞迴呼叫函式,浪費空間,並且遞迴太深容易造成堆疊的溢位。

相關文章