1. 程式人生 > >尾遞迴(簡要)

尾遞迴(簡要)

舉個栗子   ---    簡單粗暴

function  fac(n) {
    if(n===1) return 1;
    return  n * fac(n -1);
}
fac(5);

  n有幾次就會呼叫幾次,eg:

fac(5);

fac(5(4)fac(3));

fac(5(4(3fac(2));

fac(5(4(3(2fac(1));

fac(5(4(3(2)));

fac(5(4(6)));

fac(5*24)

120;

函式呼叫時,每此呼叫一次就會儲存一次記錄,當資料足夠大時就會記憶體溢位.

這裡需要講明的是: 函式呼叫會產生“呼叫記錄(儲存著函式的相關資訊)”存放在棧中,當有函式返回,對應的呼叫記錄才會消失,

         上述用普通遞迴實現的階乘的執行過程中,不斷的呼叫自身,導致一直沒有返回,這樣也就不斷的在棧中儲存呼叫記錄

         而當呼叫自身的次數過多後,就會產生我們常說的“棧溢位”

擬人描述: 就想一個人不斷地借錢(呼叫自身,不斷向棧中存呼叫記錄),但是總想著以後再還(一直沒有返回),

     當外債積累到超出自己償還能力的時候,就跑路了(棧溢位)

function fac(n, total) {
  if (n === 1) return total;
  return fac(n - 1, n * total);
}

fac(5, 1) // 120

  

執行過程如下:

fac(5,1)

fac(4,5)

fac(3,20)

fac(2,60)

fac(1,120)

說明:永遠只有一個呼叫記錄,呼叫函式產生一個呼叫記錄,最後一步操作 return fac(n - 1, n * total) 

   把當前函式的計算結果當做引數傳遞給了下一個自身呼叫,這樣第一個函式呼叫產生的呼叫記錄就消失了,因為它執行完了

   依次類推,就不會溢位.