2016-08-23 149 views
2

我正在閱讀一本名爲「Think Java:如何像計算機科學家一樣思考」的書,最近我介紹了遞歸方法。逆向遞歸java方法

public static void countdown(int n) 
{ 
    if (n == 0) { 
     System.out.println("Blastoff!"); 
    } else { 
     System.out.println(n); 
     countdown(n - 1); 
    } 
} 

這將是用來降低到0計數正常的遞歸方法,我明白髮生了什麼,但如果你做遞歸調用之前的System.out.println這樣

public static void countdown(int n) 
{ 
    if (n == 0) { 
     System.out.println("Blastoff!"); 
    } else { 
     countdown(n - 1); 
     System.out.println(n); 
    } 
} 

它的計數方式是相反的,所以如果我爲這兩個條件陳述給出了論點3,那麼第一個就是「3,2,1,Blastoff!」但第二個1會出現「Blastoff,1,2,3」....我不明白這是如何工作的,有人可以試着解釋在這段代碼中發生了什麼,它會以相反的方式進行計數?

+0

爲了更好地理解它是如何工作,把println的是第一種方法行。 – RominaV

回答

0

它不算「相反的方式」,它只是按照您可能沒有預料到的順序「解開」。嘗試寫出你期望發生的事情,我會很樂意幫助解決這種誤解。

+0

1秒讓我寫出來並編輯這個WTF?爲什麼我不能在不保存的情況下輸入 –

+0

在第二個函數中,遞歸調用發生在* println之前,因此首先達到基本情況(當n == 0時爲真)。然後它返回,到達前一個調用的'println'並打印'3',然後返回等等。 – EntangledLoops

+0

編輯:感謝清除那個,我明白它是如何調用倒計時並跳過System.out.println,只有怪異的對我而言,n是等於0之後的遞歸調用繼續計數。 –

0

問題在於打印行將等到您的函數調用完成。因此它會在到達第一個打印線之前連續調用該函數3次

0

遞歸的要點是每一步都有自己的「棧幀」,它有自己的局部變量,它記住了。

因此,即使在一次迭代中更改n,調用此迭代的函數仍將保留其自己的值n。當需要打印這個n時,它仍然是原始值(比下一次迭代中的值大)。

4

認爲它這樣......在第一種情況下,你將總是先下去下一功能打印,所以......

countdown(3) 
    System.out.println(3) 
    countdown(2) 
    System.out.println(2) 
    countdown(1)  
     System.out.println(1) 
     countdown(0) 
     System.out.println("Blastoff") 

結果:3 2 1升空

在第二種情況,是因爲你先打印出來,你的運行將一路走下來遞歸直到基本情況開始打印......

countdown(3) 
    countdown(2) 
    countdown(1) 
     countdown(0) 
     System.out.println("Blastoff") 
    System.out.println(1) 
    System.out.println(2) 
System.out.println(1) 

結果:1 2 3升空

遞歸很難!我希望我幫助:)

9

我會盡量爲你想象它。

第一種方法

countdown(3)    (first call) 
"3"       (sysout) 
    countdown(3-1)   (second call) 
    "2"      (sysout) 
     countdown(2-1)  (third call) 
     "1"     (sysout) 
      countdown(1-1) (fourth call) 
       "Blastoff!" (n == 0) 

方法二

countdown(3)    (first call) 
    countdown(3-1)   (second call) 
     countdown(2-1)  (third call) 
      countdown(1-1) (fourth call) 
       "Blastoff!" (n == 0. going back up call stack) 
      "1"    (sysout) 
     "2"     (sysout) 
    "3"      (sysout)