简体   繁体   中英

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. 2 - 1 = 1
  3. 1 is bigger than 0
  4. 1 - 1 = 0
  5. 0 is not bigger than 0
  6. Now we jump to this line: System.out.println(n * 4);
  7. 1 * 4 = 4
  8. 2 * 4 = 8
  9. Here I do not understand why I get one more "4" of output

What is happening in step 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

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

It means it runs totally mystery(1) twice time. First it run mystery(1) which gets ouput 4, but the next two recursion with mystery(0) ends in vein. Therefore it continues to

System.out.println(n * 4);

Which is 8

Then it runs mystery(1) once again which prints 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(1);
System.out.println(8);
mystery(1);

Therefore your main method might just as well say

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

You can replace both of those mystery(1); calls by

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

This means that the main method might just as well say

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

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. 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. A(2-1) -> A(1) // n>0, so call A()
  3. A(1-1) -> A(0) // n == 0, so nothing happens
  4. return from (3)
  5. println(1*4) -> 4
  6. return from (2)
  7. println(n*4) -> println(2*4) -> 8
  8. B(2-1) -> B(1) // we're back to the original (1) call of mystery
  9. A(1-0) -> A(0) // etc...

here I do not understand why I get one more time 4 as output what is happening in step 9 ???

Because n does not get modified. So you will run it one more time with mystery(2-1);

If you replace your n with 2, you will see 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); One before, and one after System.out.println

Since all the mystery(2-1); will result of printing 4, Hence the result 4 8 4

To understand replace mystery(n-1) to code in mystery:

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
         ...
      }
   }

}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM