int Fib(int n) { if( n < 2) return n; return (Fib(n-1)+Fib(n-2)); }
這樣寫出來的代碼很簡潔,來分析一下它的執行過程,咱們給n=5:
可能這樣你還看不出問題,其實上面的圖至關是一個樹狀結構:
紅色的部分在以後又會被求到,若是咱們給的數值不是5是一個更大的數,則被重複計算和調用的數和次數會變得更多。可見,在這樣一個過程當中,咱們把某些值一直在重複計算,再加上重複的開闢棧空間,使得它的效率變得很是低,大家能夠試着求一下第40 50個斐波那契額。
二、尾遞歸
尾部遞歸是一種編程技巧。若是在遞歸函數中,遞歸調用返回的結果總被直接返回,則稱爲尾部遞歸。尾部遞歸的函數有助將算法轉化成函數編程語言,並且從編譯器角度來講,亦容易優化成爲普通循環。這是由於從電腦的基本面來講,全部的循環都是利用重複移跳到代碼的開頭來實現的。若是有尾部歸遞,就只須要疊套一個堆棧,由於電腦只須要將函數的參數改變再從新調用一次。
1 int Fib(int n, int ret1, int ret2)
2
3 {
4 if (n ==0 )
5 {
6 return ret1;
7 }
8 else
9 {
10 return Fib(n - 1, ret2, ret1 +ret2);
11 }
12 }
int Fib(int n) { int num1 = 1; int num2 = num1; int num3 = num1; while (n > 2) { num3 = num1 + num2; num1 = num2; num2 = num3; n--; } return num3; }