演算法(Java筆記)—遞推&遞迴求解斐波拉契數列
阿新 • • 發佈:2018-12-12
遞推演算法——理性思維模式的代表,其原理是根據已有的資料和關係,逐步推導而得到結果。
演算法的執行過程:
- 根據已知結果和關係,求解中間結果。
- 判定是否達到要求,未達到則繼續重複第一步,直到尋找到正確答案。
遞迴演算法——在程式中不斷地反覆呼叫自身來達到求解問題的方法,重點是呼叫自身。
編寫遞迴方法時,必須使用if語句強制方法在未執行遞迴呼叫之前返回,如果不這樣做,它將永遠不會返回(這很重要)。
從理論上說,所有的遞迴函式都可以轉換為迴圈函式,然而代價通常都是比較高的。但遞迴是用棧機制實現的(c++),每深入一層,都要佔去一塊棧資料區域,對巢狀層數深的一些演算法,遞迴會力不從心,空間上會以記憶體崩潰而告終,而且遞迴也帶來了大量的函式呼叫,這也有許多額外的時間開銷。所以在深度大時,它的時空性就不好了。
遞迴呼叫分兩種情況:
- 直接遞迴:就是指在方法呼叫方法本身。
- 間接遞迴:指在另一個方法中呼叫遞迴方法(如前面提到的圖的遍歷),間接遞迴用的不多。
遞推與遞迴的區別:
- 從程式上看,遞迴表現為自己呼叫自己,遞推則沒有這樣的形式。
- 一般來說,遞推的效率高於遞迴
- 遞迴最終求得問題是逆向的,遞推是從簡單問題出發,一步步的向前發展,最終求得問題。是正向的。
程式碼實現:
例項:斐波拉契數列(兔子產仔問題)——一對兩個月大的兔子以後每個月可以產仔一對,新生兔兩個月後又可以產仔,也就是說,一月份出生,三月份才可以產仔,假定兔子沒有死亡,問n月後兔子的數量;
分析:
- 第一個月:1對兔子;
- 第二個月:1對兔子;
- 第三個月:2對兔子;
- 第四個月:3對兔子;
- 第五個月:5對兔子;
- 即從第三個月開始,每個月的兔子對樹等於前兩個月的兔子數的總和;
遞推演算法求解:
// 遞推演算法例項——斐波拉契數列——兔子產仔問題(1,1,2,3,5,8,13...) int diTui2(int n) {// n表示月份 int temp1, temp2, tempn; temp1 = 1;// 兩個月前的兔子對數 temp2 = 1;// 一個月前的兔子對數 tempn = 0;//n月的兔子對數 for (int i = 3; i <= n; i++) { tempn = temp1 + temp2; temp1 = temp2; temp2 = tempn; } return tempn; }
遞迴演算法求解:
// 遞迴演算法例項——斐波拉契數列——兔子產仔問題(1,1,2,3,5,8,13...)
int diTui(int n) {// n表示月份
int temp1, temp2;
if (n == 1 || n == 2) {
return 1;
} else {
temp1 = diTui(n - 1);// 一個月前的兔子對數
temp2 = diTui(n - 2);// 兩個月前的兔子對數
return temp1 + temp2;
}
}
//遞迴演算法例項——階乘問題——如5!(5的階乘)=5x4x3x2x1=120;
int diGui(int n){
if(n==1){
return 1;
}
return n*diGui(n-1);
}