为什么递归对递归调用的不同放置采取不同的行为

时间:2013-09-07 06:55:22

标签: java recursion

我试图了解递归是如何工作的。由于递归调用的放置,我有两个具有不同输出的代码。我知道支持不同的输出,但我不明白为什么输出是它的。

代码1(打印后放置的递归调用):

public class Test {
    public static void main(String[] args) {
        xMethod(5);
    }

    public static void xMethod(int n) {
        if (n > 0) {
            System.out.print(n + " ");
            xMethod(n - 1);
        }
    }
}

上面的输出是5 4 3 2 1.我理解为什么我得到这个输出。这是因为首先打印5,然后打印5,打印4,依此类推。

当我在打印之前放置递归调用时,我不明白的是以下代码的输出。

代码2(打印前的递归调用):

public class Test {
    public static void main(String[] args) {
        xMethod(5);
    }

    public static void xMethod(int n) {
        if (n > 0) {
            xMethod(n - 1);
            System.out.print(n + " ");
        }
    }
}

上面的输出是1 2 3 4 5.我无法弄清楚为什么我得到这个输出。我想象输出为4 3 2 1,因为扣除了5,然后打印为4,依此类推。但事实显然并非如此。

有人可以帮我理解递归过程中发生了什么吗?

4 个答案:

答案 0 :(得分:5)

在第一种情况下,打印完成然后调用。

在第二种情况下,调用以这种方式发生:

x(5) -> x(4) -> x(3) -> x(2) -> x(1) -> print(1) ->print(2) ->print(3) ->print(4) -> print(5)

从结束通话开始打印。

x(5)
  |
  x(4)                            print(5)
    |                             | 
    x(3)                    print(4)
      |                     |
      x(2)            print(3)
        |             |
        x(1)    print(2)
          |     | 
          print(1)  

如果是第一次

  print(5)
  x(5)
  |
  print(4)
  x(4)                            
    |
    print(3)                             
    x(3)                    
      |
      print(2)                     
      x(2)            
        | 
        print(1)  
        x(1)    

答案 1 :(得分:1)

在第二段代码中:  除非所有递归调用都已完成,否则不会执行System.out.print(n + " ");

递归函数在执行打印行之前调用自身。

答案 2 :(得分:1)

在第一个脚本中,

public static void xMethod(int n) {
    if (n > 0) {
        System.out.print(n + " ");
        xMethod(n - 1);
    }
}

在步骤进入递归调用之前打印输出。

在第二个脚本中,

public static void xMethod(int n) {
    if (n > 0) {
        xMethod(n - 1);
        System.out.print(n + " ");
    }
}

该函数保持步进“进入”递归,即一旦调用xMethod(n-1),就不执行它下面的行,即print语句。并且这一直持续到最后一次递归调用已经执行,即当x == 1时,然后调用返回并启动所有以x == 1的print语句开头的print语句,然后是x == 2的print语句等等直到第一次调用的最后一个print语句。

答案 3 :(得分:1)

我列出了第二个代码段执行流程的堆栈跟踪(希望我能更好地对齐表格和4列更好)

如果在调试程序时单步执行程序,您将获得类似的堆栈跟踪,告诉您在逐步执行程序执行流程时变量的值,列表类似于下面列出的信息:

堆栈跟踪|变量n的值声明执行|输出


   main
    xmethod(5)          5               xmethod(4)
     xmethod(4)         4               xmethod(3)
      xmethod(3)        3               xmethod(2)
       xmethod(2)       2               xmethod(1)
        xmethod(1)      1               xmethod(0)
         xmethod(0)     0               
        xmethod(1)      1            System.out.print(1 + " ")                1
       xmethod(2)       2            System.out.print(2 + " ")                1 2
      xmethod(3)        3            System.out.print(3 + " ")                1 2 3
     xmethod(4)         4            System.out.print(4 + " ")                1 2 3 4
    xmethod(5)          5            System.out.print(5 + " ")                1 2 3 4 5

您应该通过本教程(http://www.vogella.com/articles/EclipseDebugging/article.html)来掌握调试知识。调试程序将帮助您开始自己解决像这样的查询。