2016-01-23 167 views
0

我的工作包我的周圍遞歸頭,也許我太迷戀,但這裏有雲:邏輯的階乘遞歸調用

在JavaScript代碼

var factorial = function(number) { 
    // If the number is negative, it doesn't have a factorial. Return an 
    // impossible value to indicate this. 
    if (number < 0) { 
    return -1; 
    } 

    // If the number is zero, its factorial is one. 
    if (number === 0) { 
    return 1; 
    } 

    // If the number is neither illegal nor zero, call factorial again, 
    // this time passing in a smaller number. Eventually we'll reach 0, 
    // causing each call to return to its caller and the recursion terminates. 

    return number * factorial(number - 1); 
}; 

factorial(5); 

遞歸函數返回120像預期的那樣,但是爲什麼?

在抽出的邏輯,兩件事情我絆倒:1)這是爲什麼即使操作; 2)雖然是可操作的,爲什麼不就返回-1?

1)這是爲什麼即使操作?:

在底部繪製了這一點,堵漏5作爲參數,在return語句,我們得到的回報5 *階乘(5 - 1)。爲什麼這與預期的20相等?我們是不是調用函數返回5 * 階乘(5-1)的值?我們怎樣才能乘以5甚至還沒有確定的東西的價值呢?如果這只是5 *(5-1)= 20,那麼這是顯而易見的,甚至階乘(5)*(5-1)= 20有道理..

2)雖然是可操作的,爲什麼不它返回-1 ?:

與上面的情況下,最終,我們會在遞歸的地步,它會像1個*階乘(1-1)... 1 *(1- 1)= 0.然後用這個函數把數字插入到它自己的操作中,並且用我們的基本情況說「如果插入的整數爲零,停止操作並返回-1」。爲什麼在這裏沒有發生?

道歉,如果這似乎很簡單,我可能會使其成爲一個更大的交易比需求要。我只想學習:)。

回答

0

大問題 - 很高興你在深入遞歸的頭!

讓我們通過這是怎麼回事:

我們先從factorial(5)。正如你所指出的那樣,這返回5 * factorial(5-1)。爲了解factorial(5-1)是什麼,我們必須再次調用factorial函數。

factorial(5-1)回報4 * factorial(4-1)。讓我們用這個替代我們上面的東西。這給了我們5 * 4 * factorial(4-1)。我們再次做factorial(4-1)並替換它。這給了我們5 * 4 * 3 * factorial(3-1)

如果我們繼續,我們得到5 * 4 * 3 * 2 * factorial(2-1),然後5 * 4 * 3 * 2 * 1 * factorial(1-1)

現在在這裏發生了不同的事情。 factorial(1-1)回報1每if條件:

// If the number is zero, its factorial is one. 
if (number === 0) { 
    return 1; 
} 

因此,我們必須5 * 4 * 3 * 2 * 1 * 1其中= 120 = 5!如我們所期望的除非我們輸入負數,否則我們永遠不會打number == -1。對於任何正數,number == 0條件將每次捕獲。

+0

啊哈!哇,非常感謝winOWes的清晰解釋。非常感謝你! – jb07

+0

@ jb07如果這是正確的答案 - 你會介意標記爲這樣嗎?謝謝! – winhowes

+0

明白了。希望我做到了這一點(我還沒有'代表'upvote呢:)) – jb07

1

要通過甚至還沒有被確定尚的東西值增加winhowes的回答

我們怎麼能乘5?

那麼,我們沒有,直到我們知道factorial(5-1)的價值。當調用factorial(5-1)時,我們實際上並沒有進行乘法運算,直到我們對此有明確的答案。所以5在那裏等待函數調用返回的結果,但是然後4也等待factorial(4-1) ..等等。一旦最後的調用(即factorial(1))返回一個明確的答案,它乘以任何正在等待的它,並且這反過來又乘以前面的等待呼叫。

所以你有一個自上而下的方法調用,當你有了這些值,就會出現乘法運算的自下而上的情況。如圖所示:

enter image description here

+0

感謝您的解釋!查看操作的順序對我來說很有用。像上面所做的那樣,對書籍/資源的任何建議將填補這些空白嗎? – jb07

+0

你將能夠在那裏找到大量的書籍來解釋遞歸和一般編程的其他「基本」部分,但不幸的是,我不能特別指出任何東西。我剛剛在uni學到了這些,但在這種情況下谷歌搜索真的是你最好的選擇。當你開始編程時,遞歸肯定是令人困惑的部分之一,但是如果它能夠完成這個工作,那麼你就可以做到最好,而不僅僅是讓它發揮作用,而是試着去理解實際發生的事情。這會對你有很大的好處:)所以保持它。 – mavili

+0

也,如果你認爲我的答案在某些方面幫助你,請隨時upvote :) – mavili