從菲波那切數列看尾部呼叫優化

2022-06-02 18:33:10 字數 1193 閱讀 3157

1、菲波那切數列

在數學上,斐波那契數列以如下被以遞迴的方法定義:f0=0,f1=1,fn=fn-1+fn-2(n>=2,n∈n*),用文字來說,就是斐波那契數列列由 0 和 1 開始,之後的斐波那契數列係數就由之前的兩數相加。形如:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……
數學上的計算公式是:

讀書時候還有利用線性方程推算過這個公式,不過現在都忘了差不多了 ~~淚奔~~。

其實用**描述兔子生娃的故事也沒少幹,常見演算法有遞迴法和遞推法。

2、遞迴

function fibonacci(n)
說明: 

遞迴造成了大量的重複計算,使用遞迴計算大數字時,效能會特別低。

函式呼叫會在記憶體形成乙個"呼叫記錄",又稱"呼叫幀"(call frame),儲存呼叫位置和內部變數等資訊。如果在函式a的內部呼叫函式b,那麼在a的呼叫記錄上方,還會形成乙個b的呼叫記錄。等到b執行結束,將結果返回到a,b的呼叫記錄才會消失。如果函式b內部還呼叫函式c,那就還有乙個c的呼叫記錄棧,以此類推。所有的呼叫記錄,就形成乙個"呼叫棧"(call stack)。因而,當遞迴層數過大之後,就可能造成呼叫棧占用記憶體過大或者溢位。

3、遞推法

function

fibonacci(n)

return

current;

}

4、 尾呼叫優化

尾呼叫優化是指某個函式的最後一步是呼叫另乙個函式。

最簡單模式:

function f(x)
結合上面的遞迴說明,尾呼叫由於是函式的最後一步操作,所以不需要保留外層函式的呼叫記錄,因為呼叫位置、內部變數等資訊都不會再用到了,只要直接用內層函式的呼叫記錄,取代外層函式的呼叫記錄就可以了。   

菲波那切數列改寫成尾呼叫寫法:

'use strict'

function fibonacci(n, current = 0, next = 1)

5、動態規劃

function fibonacci(n) 

return sum

}

參考:阮一峰--《尾呼叫優化》

菲波那切數列

防止明天沒有時間或者忘了寫,今天先寫下吧。如果一對兔子每月生一對兔子 一對新生兔,從第二個月起就開始生兔子 假定每對兔子都是一雌一雄,試問一對兔子,一年能繁殖成多少對兔子?首先這個題目的設定是原來的一對兔子在一開始是新生的兔子,這樣這對兔子在第二個月才能生下一對新的兔子 也就是第三個月開始,第二個月...

菲波那切數列

現在已知fibonacci 菲波那切 數列的前幾項0 1 1 2 3 5 8 程式設計求出第 n 項。輸入一行,包含乙個正整數n 1 n 50輸出乙個整數。有兩種實現方式 1.遞迴實現 include include using namespace std long long f int n int...

菲波那切數列

題目描述 大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項 從0開始,第0項為0 n 39 時間限制 c c 1秒,其他語言2秒 空間限制 c c 32m,其他語言64m 熱度指數 808696 class solution def fibonacci self,n wr...