1. 程式人生 > >猴子吃桃遞迴和尾遞迴--JavaScript版

猴子吃桃遞迴和尾遞迴--JavaScript版

有一隻猴子摘了一堆桃子,當即吃了一半,可是桃子太好吃了,它又多吃了一個,第二天它把第一天剩下的桃子吃了一半,又多吃了一 個,
就這樣到第十天早上它只剩下一個桃子了,問它一共摘了多少個桃子?(1534)

逆向思維實現


 var day = 9;
 var total = 0;
 var lastNum   = 1 ;//第十天只剩下一個桃子
 while(day>0){

   lastNum =  (lastNum+1)*2;
   total = lastNum;
   day--;

 }

 alert("total="+ total);

用for迴圈來搞搞:


     var day = 9;
     var total = 0;
     var lastNum   = 1 ;//第十天只剩下一個桃子


     for(var day = 9;day > 0;day--){

       lastNum =  (lastNum+1)*2;
       //total = lastNum;
     }

     alert("total="+ lastNum);

關於遞迴

關於遞迴的概念,我們都不陌生。簡單的來說遞迴就是一個函式直接或間接地呼叫自身,是為直接或間接遞迴。一般來說,遞迴需要有邊界條件、遞迴前進段和遞迴返回段。當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回。用遞迴需要注意以下兩點:

  • 遞迴就是在過程或函式裡呼叫自身。
  • 在使用遞迴策略時,必須有一個明確的遞迴結束條件,稱為遞迴出口。

遞迴一般用於解決三類問題:

  • 資料的定義是按遞迴定義的。(Fibonacci函式,n的階乘)
  • 問題解法按遞迴實現。(回溯)
  • 資料的結構形式是按遞迴定義的。(二叉樹的遍歷,圖的搜尋)

遞迴的缺點:
  遞迴解題相對常用的演算法如普通迴圈等,執行效率較低。因此,應該儘量避免使用遞迴,除非沒有更好的演算法或者某種特定情況,遞迴更為適合的時候。在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存,因此遞迴次數過多容易造成棧溢位。1

遞迴實現



  function
calclPeach(day) {
/* var total;//定義函式返回值即桃子總數 if(day == 1)//如果是最後一天時 total = 1;//桃子在最後一天時數目 else total = 2 * (calculate(day - 1) + 1);//前一天的桃子數目等於後一天數量加1乘2 return total ;//遞迴返回桃子數 */ if(day ==1) return 1;//桃子在最後一天時數目 return 2 * (calclPeach(day - 1) + 1); } alert("猴子摘了桃子數="+calclPeach(10));

遞迴

尾遞迴實現


    function tailRecursivePeach(day,result)
   {

       if(day == 1)
       {
         return result;
       }

       return tailRecursivePeach(day-1,2 * (result+1));

    }

尾遞迴

發現尾遞迴在瀏覽器不管用,還是出現了棧記憶體溢位!!難道是瀏覽器底層不支援?