算法第四版35頁問題1.1.27,估計用一下代碼計算binomial(100,50,0.25)將會產生的遞歸調用次數:算法
public static double binomial(int n,int k,double p){ if(n == 0 && k == 0) return 1.0; if(n<0 || k<0) return 0.0; return (1.0-p)*binomial(n-1,k,p) +p*binomial(n-1,k-1,p) }
雖然書上只讓估計調用次數,可是以爲想知道到底調用了幾回。函數
我用圖畫出遞歸調用的狀況spa
能夠看出遞歸中有不少重複調用好比,第4層遞歸 分別調用了binomial(n-3,k-1,p)和binomial(n-3,k-2,p)三次。這就是這個算法效率低的緣由。能夠看出重複調用的次數是一個楊輝三角。3d
根據楊輝三角的性質,code
第m層遞歸函數被調用的狀況爲:blog
第m層第x(x<=m)項爲:遞歸
可是有些調用實際上不會發生,結合函數的返回條件:get
if(n == 0 && k == 0) return 1.0; if(n<0 || k<0) return 0.0;
設咱們傳入的初始參數爲n=N,k=K 則,能夠得出已下結論:it
讓咱們看看知足以上結論的詳細項:class
1.下列遞歸調用的x>K+1,知足結論2:
2.m=N+1行的第K+1項遞歸調用的第一個參數n和第二個參數k均爲0,知足結論1。
3.當m=N+2時,顯然m>N+1,知足結論2;
若是調用參數知足函數退出條件,那麼由調用的遞歸實際上就不會發生,數量爲的係數✖️2。
N+2以後的遞歸都不會發生,因此作計算時只考慮到N+2層。N+2層的無效調用數量,爲N+1層知足結論1或2的調用的數量*2,一次類推,直到K+3層的無效調用數量,爲K+2層知足結論1或2的調用數量*2;K+2層到1層上,全部調用都有效;由於K+1層到1層,沒有調用知足結論1或2.
根據楊輝三角的性質:從第1層到第N+2層全部的係數和爲
其中不會實際發生的調用次數爲從(K+2層到N+1層):
化簡以後爲:
再次化簡
因此最後程序遞歸調用的總次數爲
運行隨機驗證幾個組合,能夠證實上述公式是正確的!