斐波那契數列的遞迴演算法與非遞迴演算法

2021-10-07 14:52:00 字數 1329 閱讀 4940

一、斐波那契數列

由於斐波納挈數列是以兔子的繁殖引入的,因此也叫「兔子數列」。它指的是這樣乙個數列:0,1,1,2,3,5,8,13......從這組數可以很明顯看出這樣乙個規律:從第三個數開始,後邊乙個數一定是在其之前兩個數的和。在數學上,斐波納挈數列可以以這樣的公式表示:f(0) = 0 f(1) = 1 f(n) = f(n-1) + f(n-2),(n>=2)

二、斐波納挈數列的實現

既然該數列已經有這樣乙個規律:f(n) = f(n-1) + f(n-2);那麼我們很容易就能想到用遞迴的方法,這樣寫出來的**比較簡潔

long long fib1(long long num)

return fib1(num-1)+fib1(num-2);

}

當然,我們也可以這樣寫:

long long fib1(long long num)

這樣的遞迴演算法雖然只有簡單的幾行,但是效率卻很低。為什麼呢?我們可以分析其遞迴呼叫的時間複雜度:

時間複雜度 ----- o(2^n)

由於使用遞迴時,其執行步驟是:要得到後乙個數之前必須先計算出之前的兩個數,即在每個遞迴呼叫時都會觸發另外兩個遞迴呼叫,例如:要得到f(10)之前得先得到f(9)、f(8),那麼得到f(9)之前得先得到f(8)、f(7)......如此遞迴下去

從上圖我們可以看出,這樣的計算是以 2 的次方在增長的。除此之外,我們也可以看到,f(8)和f(7)的值都被多次計算,如果遞迴的深度越深,那麼f(8)和f(7)的值會被計算更多次,但是這樣計算的結果都是一樣的,除了其中之一外,其餘的都是浪費,可想而知,這樣的開銷是非常恐怖的!

所以,如果在時間複雜度和空間複雜度都有要求的話,我們可以用以下兩種非遞迴演算法來實現:

@@:時間複雜度為o(n),空間複雜度為o(n)

建立乙個陣列,每次將前兩個數相加後直接賦給後乙個數。這樣的話,有n個數就建立乙個包含n個數的一維陣列,所以空間複雜度為o(n);由於只需從頭向尾遍歷一邊,時間複雜度為o(n)

long long* fib2(long long num)

return array;

}

@@:時間複雜度為o(n),空間複雜度為o(1)

借助兩個變數 first 和 second ,每次將 first 和 second 相加後賦給 third ,再將 second 賦給 first ,third 賦給 second,如此迴圈。

long long fib3(long long num)

return third;

}

斐波那契數列 遞迴與非遞迴

首先來說下遞迴,遞迴的思想是大事化小。斐波那契數列 1,1,2,3,5,8,13,21.設f n 是第n個斐波那契數,當n 2,斐波那契數都為1 當n 2,那麼第f n 個斐波那契數就等於前兩個斐波那契數之和。遞迴的 實現 includeint fbnq int n int main 輸入10,得到...

數學 斐波那契數列 遞迴 非遞迴

include pch.h include using std cout using std cin typedef long long ll int fib int n ll fib notrec int n int main return 0 題目給的f 0 1,就這麼寫了 斐波那契第n項 時間...

斐波那契數列的遞迴和非遞迴演算法

2014 04 20 斐波那契數列 演算法速度 fbi4 fbi3 fbi2 fbi1 include include include include 開始計時 void start timer struct timeval tv 流逝的時間 微秒 long long get time elapse...