斐波那契數列的三種演算法以及複雜度

2021-08-13 20:41:26 字數 1883 閱讀 7509

原作者部落格:

(1)遞迴:函式自己呼叫自己

(2)遞迴的"缺陷":遞迴到一定程度,會發生"棧溢位"

(3)遞迴的"時間複雜度":遞迴總次數*每次遞迴的次數

(4)遞迴的"空間複雜度":遞迴的深度*每次遞迴空間的大小(注意:"每次遞迴空間的大小"是個常數,可以基本忽略不計)

遞迴的"深度":樹的高度(遞迴的過程是乙個"二叉樹")

1.遞迴實現斐波那契數列

#include

#include

long

long fib(long

long n)

int main()

執行結果: 

此種方法的缺陷:重複計算的次數太多,效率低

例如:在下圖中,f(3)就重複計算了 "3次"

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

空間複雜度:o(n)

2.遞迴(尾遞迴)實現斐波那契數列,但是時間複雜度盡可能低

尾遞迴是什麼呢? 

尾遞迴解決了遞迴重複計算的問題

"尾遞迴的前提是遞迴"

(1)定義:在乙個程式中,執行的最後一條語句是對自己的呼叫,而且沒有別的運算

(2)尾遞迴的實現:是在編譯器優化的條件下實現的

編譯器優化:

遞迴的第一次呼叫時會開闢乙份空間,此後的遞迴呼叫不會再開闢空間,而是在剛才開闢的空間上做一些修改,實現此次遞迴,例如在本題中求fib(10),編譯器會給fib(10)的呼叫開闢棧幀,呼叫fib(9)的時候不會再重新開闢棧幀,而是在剛開闢的棧幀上做一些修改,因為遞迴的每一次呼叫都是一樣的流程,只是會有一些資料不同,所以不會再開闢空間。

注:vs一般都支援優化,debug下編譯器不會優化哦,一定要在release模式下。

#include

#include

long

long fib(long

long first,long

long second ,long

long n)

int main()

執行結果:

此種方法是尾遞迴,很大程度的減小了第一種方法(遞迴實現斐波那契數列)的時間複雜度

時間複雜度:o(n-2)約等於0(n)

空間複雜度:o(n-2)約等於0(n)(編譯器如果優化的話是o(1))

此種遞迴是尾遞迴

3.迴圈實現斐波那契數列

#include

#include

long

long fib(long

long n)

return second;

}int main()

執行結果:

時間複雜度:o(n)

空間複雜度:o(1)(建立了四個物件,是常數,所以可忽略不計)

此種方法是"最優方法"

優點:時間複雜度和空間複雜度最低,而且可讀性高

斐波那契數列的三種解法

寫乙個函式,輸入n,求斐波那契數列的第n項。斐波那契數列的定義如下 課本的上為了講解遞迴演算法,經常用這個例子。讓我們看一下它的實現 package algorithm public class fibonacci recursion public static void main string a...

斐波那契數列的三種寫法

斐波那契數列,又稱 分割數列,指的是這樣乙個數列 0 1 1 2 3 5 8 13 21 34 在數學上,斐波納契數列以如下被以遞迴的方法定義 f 0 0,f 1 1,f n f n 1 f n 2 n 2,n n 在現代物理 準晶體結構 化學等領域,斐波納契數列都有直接的應用,為此,美國數學會從1...

斐波那契數列的三種實現方法

斐波那契數列是學習演算法碰到的,以自己當前的知識面還不足以想到通過公升高乙個維度來降低演算法的時間複雜度.昨天再看劍指offer的時候,在面試題9中提到了三種實現計算斐波那契數列的方法.在這裡實現三種做法貌似還有乙個o 1 的計算方法,也就是斐波那契數列是可以直接推到出來的.1.常規的遞迴演算法 d...