使用遞歸解決斐波那契數列的性能問題


我們知道斐波那契數列(也稱作兔子數列)  1,1,2,3,5,8,13,21,34。。。。。

前兩位數固定是1,之后每一位數都是前兩位數的之和,這樣的數列就是斐波那契數列

那么我們要求這樣的數列,就必須要求n-1和n-2位數

 

    function getFB(n){
      if(n == 1 || n == 2){   
    // 這里我們先保持前兩位數是1
return 1; }else { return getFB(n-1) + getFB(n-2); } } console.log(getFB(10));

求斐波那契數列的第十位   在控制台中打印出來的是 55

 

那么  第五十位呢?。。。。。。。。。

很好,我的瀏覽器卡死崩潰了

由此我們可知,這樣求斐波那契數列實在是太浪費性能了

既然有問題我們就來解決它

那么   求斐波那契數列的時候是為什么會浪費性能呢?

 

原因就是瀏覽器求了太多重復項

var i = 0; //聲明一個變量,用來記錄調用getFB()方法的次數
    function getFB(n){
      i++;
      if(n == 1 || n == 2){
        return 1;
      }else {
        return getFB(n-1) + getFB(n-2);
      }
    }
    console.log(getFB(20));// 我的瀏覽器求不出來這么多項 所以換了小一點的數字
    console.log(i);

求斐波那契數列的第20位會調用13529次函數

 

 

那么求第30位呢?

多達16萬次

 第40位呢?第50 位呢?。。。。。。。

 所以這個樣子實在是太浪費性能了

 

解決問題的思路:我們把已經求過的項用一個變量保存起來,如果下次還需要用到這個項就直接取出來用,而不是再去調用函數

 

 var i = 0;//聲明一個變量i,記錄調用getFB這個函數的次數.
    //聲明一個對象obj,用來保存已經求過的項.
    var obj = {};
    function getFB(n){
      i++;
      //求n位是多少,就先去obj里面看看,之前求過沒有,如果之前求過,就直接取出來使用.
      if(obj[n] != undefined){
        //如果進到了這里,說明當前這個n位已經求過,已經存進obj里面了
        return obj[n];
      }else {
        //如果進到這里來了,就說明當前這個n位之前沒求過,沒求過就求唄.
        if(n == 1 || n == 2){
          obj[n] = 1;
          return 1;
        }else {
          obj[n] = getFB(n-1) + getFB(n-2);
          return obj[n];
        }
      }
    }

    console.log(getFB(60));
    console.log(i);

那么我們就來看看結果吧

斐波那契數列的第60位大的嚇人,但是我們卻也只調用了117次函數,極大的提高了性能

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM