猴子吃桃遞迴和尾遞迴--JavaScript版
阿新 • • 發佈:2019-01-27
有一隻猴子摘了一堆桃子,當即吃了一半,可是桃子太好吃了,它又多吃了一個,第二天它把第一天剩下的桃子吃了一半,又多吃了一 個,
就這樣到第十天早上它只剩下一個桃子了,問它一共摘了多少個桃子?(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));
}
發現尾遞迴在瀏覽器不管用,還是出現了棧記憶體溢位!!難道是瀏覽器底層不支援?