简体   繁体   English

递归方法如何工作?

[英]How does a recursion method work?

I found this example of recursion online, but I do not understand what is happening in it. 我在网上发现了这个递归的例子,但我不明白它里面发生了什么。

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);
    }
}

the output is 输出是

4
8
4

What I understand is that 我的理解是

  1. 2 is bigger than 0 2大于0
  2. 2 - 1 = 1 2 - 1 = 1
  3. 1 is bigger than 0 1大于0
  4. 1 - 1 = 0 1 - 1 = 0
  5. 0 is not bigger than 0 0不大于0
  6. Now we jump to this line: System.out.println(n * 4); 现在我们跳到这一行: System.out.println(n * 4);
  7. 1 * 4 = 4 1 * 4 = 4
  8. 2 * 4 = 8 2 * 4 = 8
  9. Here I do not understand why I get one more "4" of output 在这里,我不明白为什么我再得到一个“4”的输出

What is happening in step 9? 第9步发生了什么?

I used a debugger but still do not understand. 我使用了调试器,但仍然不明白。

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)

If you run this code with n=2 如果您运行此代码n=2

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

It means it runs totally mystery(1) twice time. 这意味着它两次完全神秘(1)。 First it run mystery(1) which gets ouput 4, but the next two recursion with mystery(0) ends in vein. 首先它运行神秘(1)获得输出4,但接下来的两个神秘(0)递归以静脉结束。 Therefore it continues to 因此它继续

System.out.println(n * 4);

Which is 8 这是8

Then it runs mystery(1) once again which prints 4. 然后它再次运行神秘(1)打印4。

I can only understand recursion by thinking about what would happen if I copy-and-paste all the code so it's all in the same place. 我只能通过思考如果我复制并粘贴所有代码会发生什么来理解递归,所以它们都在同一个地方。

You can replace mystery(2) with the three lines 你可以用三条线代替mystery(2)

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

Therefore your main method might just as well say 因此,您的main方法也可以说

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

You can replace both of those mystery(1); 你可以取代这两个 mystery(1); calls by 打电话

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

This means that the main method might just as well say 这意味着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); effectively does nothing, so main might just as well say 实际上没有任何作用,所以main也可以说

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

You're doing a double recursion - the same function is being called TWICE. 你正在进行双递归 - 同样的函数被称为TWICE。 So your execution path is wrong. 所以你的执行路径是错误的。 Note the following change for clarity: 为清晰起见,请注意以下更改:

  mystery(n-1);   // pretend this is function "A"
  System.out.println(n * 4);
  mystery(n-1);   // pretend this is function "B"
  1. mystery(2) // start the recursion 神秘(2)//开始递归
  2. A(2-1) -> A(1) // n>0, so call A() A(2-1) - > A(1)// n> 0,所以调用A()
  3. A(1-1) -> A(0) // n == 0, so nothing happens A(1-1) - > A(0)// n == 0,所以没有任何反应
  4. return from (3) 从(3)返回
  5. println(1*4) -> 4 println(1 * 4) - > 4
  6. return from (2) 从(2)返回
  7. println(n*4) -> println(2*4) -> 8 println(n * 4) - > println(2 * 4) - > 8
  8. B(2-1) -> B(1) // we're back to the original (1) call of mystery B(2-1) - > B(1)//我们回到神秘的原始(1)召唤
  9. A(1-0) -> A(0) // etc... A(1-0) - > A(0)//等......

here I do not understand why I get one more time 4 as output what is happening in step 9 ??? 在这里我不明白为什么我再得到一次4作为输出在步骤9中发生的事情???

Because n does not get modified. 因为n没有得到修改。 So you will run it one more time with mystery(2-1); 所以你将再次以mystery(2-1);运行它mystery(2-1);

If you replace your n with 2, you will see exacly: 如果你用2替换你的n,你会看到exacly:

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

You have two calls with mystery(2-1); 你有两个mystery(2-1);电话mystery(2-1); One before, and one after System.out.println 一个之前,一个在System.out.println之后

Since all the mystery(2-1); 所有的mystery(2-1); will result of printing 4, Hence the result 4 8 4 将打印4,结果4 8 4

To understand replace mystery(n-1) to code in mystery: 要理解将神秘(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