目錄
一、斐波那契數列定義
二、兩種遞迴實現方式及分析
1、方式一:使用數學公式直接實現(二分遞迴)第n個斐波那契數
2、方式二:使用線性遞迴計算第n個斐波那契數(推薦方式)
三、對遞迴的認識
四、其他概念
斐波那契數列(fibonacci sequence),又稱**分割數列,因數學家萊昂納多·斐波那契(leonardoda fibonacci)以兔子繁殖為例子而引入,故又稱為「兔子數列」,指的是這樣乙個數列:0、1、1、2、3、5、8、13、21、34、……這個數列從第3項開始,每一項都等於前兩項之和。在數學上,斐波那契數列以如下被以遞推的方法定義:f(0)=0,f(1)=1, f(n)=f(n - 1)+f(n - 2)(n ≥ 2,n ∈ n*)
根據斐波那契數列數學定義:
f(0)=0,f(1)=1, f(n)=f(n - 1)+f(n - 2)(n ≥ 2,n ∈ n*)
如下兩種使用遞迴計算斐波那契數列的方法(python3):
def fibonacci_1(n):
if n<=1:
return n
else:
return fibonacci_1(n-2)+fibonacci_1(n-1)
這種方式中,是基於數學定義直接實現,也是很簡便的實現方法,但是,需要關注的問題是,這種方式也會直接導致方法的執行效率會非常低,會隨著n越大,其效率也更低。計算第n個斐波那契數需要對該方法進行指數級別的呼叫。假設用cn表示第n個斐波那契數需要呼叫fibonacci_1(n)的次數,有如下:
第n個斐波那契數呼叫方法次數
n=0c0=1
n=1c1=1
n=2c2=c0+c1+1=3
n=3c3=c1+c2+1=5
n=4c4=c2+c3+1=9
n=5c5=c3+c4+1=15
n=6c6=c4+c5+1=25
n=7c7=c5+c6+1=41
n=8c8=c6+c7+1=67
n=9c9=c7+c8+1=109
如果一直按照這個方式進行下去,我們可以從上表中看出,n越大呼叫次數也越多,使得呼叫的總次數時n的指數級。
使用如下程式段計算50次(windows10 cpu 1c):
if __name__ == "__main__":
t1 = time.clock()
for i in range(50):
t11 = time.clock()
print("n={},fibonacci={}".format(i,fibonacci_1(i)))
t12 = time.clock()
print("cost time:{}".format(t12-t11))
t2 = time.clock()
print("sum time:{}".format(t2-t1))
擷取了部分結果:n=31時,花費時間0.4s,但是當n=41時,需要時間52s,這樣看來n越大,效率是很低的。
n=31,fibonacci=1346269
cost time:0.43121010000000004
n=32,fibonacci=2178309
cost time:0.714747
n=33,fibonacci=3524578
cost time:1.3300094999999998
n=34,fibonacci=5702887
cost time:1.7607852999999998
n=35,fibonacci=9227465
cost time:2.8848124000000004
n=36,fibonacci=14930352
cost time:4.900053
n=37,fibonacci=24157817
cost time:7.670326699999999
n=38,fibonacci=39088169
cost time:13.099861399999998
n=39,fibonacci=63245986
cost time:20.710187599999998
n=40,fibonacci=102334155
cost time:32.3978941
n=41,fibonacci=165580141
cost time:52.244939900000006
def fibonacci_2(n):
if n<=1:
return (n,0)
else:
(a,b) = fibonacci_2(n-1)
return (a+b,a)
方式二每次只呼叫fibonacci_2方法一次,該方法每次返回一對連續的斐波拉契數列,而不是返回乙個斐波那契數,在o(n)時間內完成整體計算。
同樣計算50次,擷取了部分結果如下:每次花費的時間都非常小,總共的時間也在1秒以內。
n=32,cost time:7.000000000000062e-06
n=33,cost time:7.299999999994811e-06
n=34,cost time:7.699999999999374e-06
n=35,cost time:7.900000000005125e-06
n=36,cost time:8.100000000003937e-06
n=37,cost time:8.099999999996998e-06
n=38,cost time:8.399999999998686e-06
n=39,cost time:8.500000000001562e-06
n=40,cost time:8.79999999999631e-06
n=41,cost time:8.899999999999186e-06
n=42,cost time:9.200000000000874e-06
n=43,cost time:9.500000000002562e-06
n=44,cost time:9.699999999994435e-06
n=45,cost time:9.80000000000425e-06
n=46,cost time:1.0200000000001874e-05
n=47,cost time:1.0599999999999499e-05
n=48,cost time:1.0700000000002374e-05
n=49,cost time:1.0999999999997123e-05
使用遞迴時,就效率而言,效率低的遞迴和效率高的遞迴,就如同白天和黑夜,差別懸殊。對於乙個實際問題,對於遞迴演算法的設計顯得尤為重要。另乙個需要注意的問題是在遞迴誤用,避免出現無限遞迴,會很快耗盡計算機資源,不僅僅是cpu的使用,也會因連續不斷的呼叫建立需要的記憶體資源。
1、線性遞迴
每個呼叫中至多執行呼叫乙個新的遞迴呼叫
2、二路遞迴
乙個遞迴函式執行呼叫兩個遞迴函式時,稱為二路遞迴
3、多重遞迴
乙個遞迴函式執行呼叫三個或三個以上遞迴函式時,稱為多重遞迴
迴圈斐波那契數列 斐波那契數列的兩種實現
最先研究這個數列的人是義大利人斐波那契,leonardo fibonacci,他在描述兔子生長的數目時用上了這數列 每個月兔子的總對數,就是這樣乙個序列 1,1,2,3,5,8,13,21.這個序列從第三項開始,每一項都等於前兩項之和。在數學上,斐波那契數列是以遞迴的方法來定義 f 1 1 f 2 ...
php 兩種方式實現求 斐波那契數 遞迴,遞推
斐波那契數,亦稱之為斐波那契數列 義大利語 successione di fibonacci 又稱 分割數列 費波那西數列 費波拿契數 費氏數列,指的是這樣乙個數列 1 1 2 3 5 8 13 21 在數學上,斐波那契數列以如下被以遞迴的方法定義 f 0 0,f 1 1,fn f n 1 f n ...
斐波那契數列 的兩種實現方式
一 先要回答乙個問題 什麼是婓波那契數列?答案在這裡 二 看 1 第一方法 遞迴實現 public static void main string args public static int fibonacci int i else if i 1 return fibonacci i 2 fibo...