Java 递归方法是如何工作的?

Java 递归方法是如何工作的?,java,Java,我在网上找到了这个递归的例子,但我不明白其中发生了什么 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

我在网上找到了这个递归的例子,但我不明白其中发生了什么

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
我的理解是

  • 2大于0
  • 2-1=1
  • 1大于0
  • 1-1=0
  • 0不大于0
  • 现在我们跳到这一行:
    System.out.println(n*4)
  • 1*4=4
  • 2*4=8
  • 在这里,我不明白为什么我又得到了一个“4”的输出
  • 步骤9中发生了什么


    我使用了调试器,但仍然不理解。

    如果将n替换为2,您将看到:

    if (2 > 0) {
      mystery(2-1); // prints 4
      System.out.println(2 * 4);
      mystery(2-1); // prints 4
    }
    
    您有两个调用
    神秘(2-1)一个在前面,一个在后面
    System.out.println


    因为所有的
    神秘(2-1)
    将作为打印4的结果,因此,如果使用
    n=2运行此代码,则结果为4 8 4

      mystery(n-1);
      System.out.println(n * 4);
      mystery(n-1);
    
    这意味着它两次运行完全神秘。首先它运行神秘(1),得到输出4,但接下来的两个神秘(0)递归以vein结束。因此,它继续

    System.out.println(n * 4);
    
    哪一个是8

    然后它再次运行神秘号(1),打印4

    在这里,我不明白为什么我又得到一次4作为输出,步骤9中发生了什么


    因为
    n
    不会被修改。因此,您将使用
    神秘(2-1)再次运行它

    您正在执行双重递归-同一函数被调用两次。所以你的执行路径是错误的。为清晰起见,请注意以下更改:

      mystery(n-1);   // pretend this is function "A"
      System.out.println(n * 4);
      mystery(n-1);   // pretend this is function "B"
    
  • 神秘(2)//开始递归
  • A(2-1)->A(1)//n>0,所以调用A()
  • A(1-1)->A(0)//n==0,所以什么也不会发生
  • 返回(3)
  • println(1*4)->4
  • 返回(2)
  • println(n*4)->println(2*4)->8
  • B(2-1)->B(1)//我们回到了最初的神秘召唤
  • A(1-0)->A(0)//等等

  • 要理解将神秘(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
             ...
          }
       }
    
    }
    }
    

    我只能通过思考如果我复制并粘贴所有代码,使它们都在同一个地方,会发生什么来理解递归

    您可以用三行替换
    神秘(2)

    mystery(1);
    System.out.println(8);
    mystery(1);
    
    因此,您的
    main
    方法可能会说

    public static void main(String[] args) {
        mystery(1);
        System.out.println(8);
        mystery(1);
    }
    
    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);
    }
    
    public static void main(String[] args) {
        System.out.println(4);
        System.out.println(8);
        System.out.println(4);
    }
    
    您可以替换这两个
    神秘(1)呼叫人

    mystery(0);
    System.out.println(4);
    mystery(0);
    
    这意味着
    main
    方法也可以说

    public static void main(String[] args) {
        mystery(1);
        System.out.println(8);
        mystery(1);
    }
    
    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);
    }
    
    public static void main(String[] args) {
        System.out.println(4);
        System.out.println(8);
        System.out.println(4);
    }
    
    神秘(0)实际上什么都不做,所以
    main
    不妨说

    public static void main(String[] args) {
        mystery(1);
        System.out.println(8);
        mystery(1);
    }
    
    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);
    }
    
    public static void main(String[] args) {
        System.out.println(4);
        System.out.println(8);
        System.out.println(4);
    }
    

    首先删除最后一个“神秘(n-1)”;“谢谢你的回答,但为什么我必须删除它?因为它将按以下顺序执行以下参数的打印:->
    1,2,1
    @所有答案都来了,现在我不需要给你解释,因为已经有解决方案了。哦,我的上帝。。你的回答很清楚,很专业……非常感谢:)