繁体   English   中英

为什么递归在不同的递归调用位置上有不同的作用

[英]Why does recursion act differently for different placements of recursive call

我试图了解递归的工作原理。 由于递归调用的位置,我有两个具有不同输出的代码。 我知道应该有不同的输出,但是我不明白为什么输出是它的原样。

代码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减去1,再打印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 45。我不知道为什么得到此输出。 我可以想象输出是4 3 2 1,减去5,然后打印为4,依此类推。 但这显然不是事实。

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

在第一种情况下,打印完成,然后发生呼叫。

在第二种情况下,呼叫是以这种方式发生的:

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)    

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

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

在第一个脚本中

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语句开头,然后是x == 2的print语句直到第一个调用的最后一个打印语句。

我已经列出了第二个片段的执行流程的堆栈跟踪记录(希望我可以将表和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 )以掌握调试的窍门。 调试程序将帮助您自己亲自解决此类查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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