簡體   English   中英

遞歸方法如何工作?

[英]How does a recursion method work?

我在網上發現了這個遞歸的例子,但我不明白它里面發生了什么。

public class MysteryClass {
    public static void mystery(int n) {
        if (n > 0) {
            mystery(n-1);
            System.out.println(n * 4);
            mystery(n-1);
        }
    }
    public static void main(String[] args) {
        MysteryClass.mystery(2);
    }
}

輸出是

4
8
4

我的理解是

  1. 2大於0
  2. 2 - 1 = 1
  3. 1大於0
  4. 1 - 1 = 0
  5. 0不大於0
  6. 現在我們跳到這一行: System.out.println(n * 4);
  7. 1 * 4 = 4
  8. 2 * 4 = 8
  9. 在這里,我不明白為什么我再得到一個“4”的輸出

第9步發生了什么?

我使用了調試器,但仍然不明白。

MysteryClass.mystery(2);
    if (2 > 0) (true) ---> mystery(2-1);
    |   if(1 > 0) (true) ---> mystery (1-1); // Action (A)
    |   |   if(0 > 0) (false) ---> // do nothing 
    |   |     
    |   System.out.println(1 * 4);
    |   mystery(1-1);
    |
    System.out.println(2 * 4);
    mystery(2-1); ---> // repeat action (A)

如果您運行此代碼n=2

  mystery(n-1);
  System.out.println(n * 4);
  mystery(n-1);

這意味着它兩次完全神秘(1)。 首先它運行神秘(1)獲得輸出4,但接下來的兩個神秘(0)遞歸以靜脈結束。 因此它繼續

System.out.println(n * 4);

這是8

然后它再次運行神秘(1)打印4。

我只能通過思考如果我復制並粘貼所有代碼會發生什么來理解遞歸,所以它們都在同一個地方。

你可以用三條線代替mystery(2)

mystery(1);
System.out.println(8);
mystery(1);

因此,您的main方法也可以說

public static void main(String[] args) {
    mystery(1);
    System.out.println(8);
    mystery(1);
}

你可以取代這兩個 mystery(1); 打電話

mystery(0);
System.out.println(4);
mystery(0);

這意味着main方法也可以說

public static void main(String[] args) {
    mystery(0);
    System.out.println(4);
    mystery(0);
    System.out.println(8);
    mystery(0);
    System.out.println(4);
    mystery(0);
}

mystery(0); 實際上沒有任何作用,所以main也可以說

public static void main(String[] args) {
    System.out.println(4);
    System.out.println(8);
    System.out.println(4);
}

你正在進行雙遞歸 - 同樣的函數被稱為TWICE。 所以你的執行路徑是錯誤的。 為清晰起見,請注意以下更改:

  mystery(n-1);   // pretend this is function "A"
  System.out.println(n * 4);
  mystery(n-1);   // pretend this is function "B"
  1. 神秘(2)//開始遞歸
  2. A(2-1) - > A(1)// n> 0,所以調用A()
  3. A(1-1) - > A(0)// n == 0,所以沒有任何反應
  4. 從(3)返回
  5. println(1 * 4) - > 4
  6. 從(2)返回
  7. println(n * 4) - > println(2 * 4) - > 8
  8. B(2-1) - > B(1)//我們回到神秘的原始(1)召喚
  9. A(1-0) - > A(0)//等......

在這里我不明白為什么我再得到一次4作為輸出在步驟9中發生的事情???

因為n沒有得到修改。 所以你將再次以mystery(2-1);運行它mystery(2-1);

如果你用2替換你的n,你會看到exacly:

if (2 > 0) {
  mystery(2-1); // prints 4
  System.out.println(2 * 4);
  mystery(2-1); // prints 4
}

你有兩個mystery(2-1);電話mystery(2-1); 一個之前,一個在System.out.println之后

所有的mystery(2-1); 將打印4,結果4 8 4

要理解將神秘(n-1)替換成神秘的代碼:

int n1 = 2
if (n1 > 0){ // step 1
   int n2 = n1 - 1; // step2: 1
   if (n2 > 0){ // step 3
      int n3 = n2 - 1; // step4: 0   
      if (n3 > 0){ // step 5: false
         ...
      }
      System.out.println(n2 * 4); // step 6: print 4
      int n3_1 = n2 - 1; // step 7: 0   
      if (n3_1 > 0){ // false
         ...
      }
   }

   System.out.println(n1 * 4); // step 8: print 8

   if (n2 > 0){
      int n3 = n2 - 1; // 0   
      if (n3 > 0){ // false
         ...
      }  
      System.out.println(n2 * 4);  // step 9: print 4
      int n3_1 = n2 - 1; // 0   
      if (n3_1 > 0){ // false
         ...
      }
   }

}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM