6

有人可以向我解释为什么会打印出 1 2 3 4 5 吗?我认为它会打印出 4 3 2 1 0 但我的书和日食都说我错了。

public class whatever {

    /**
     * @param args
     */
    public static void main(String[] args) {
        xMethod(5);

    }

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


}
4

9 回答 9

19

这很简单,这些是调用

main
   xMethod(5)
      xMethod(4)
          xMethod(3)
             xMethod(2)
                 xMethod(1)
                     xMethod(0)
                 print 1
             print 2
          print 3
      print 4
  print 5

所以你看到打印是 1,2,3,4,5

于 2013-04-11T06:14:15.660 回答
5

这是调用堆栈的结果。这是与 通话后的样子n = 5。将你的头旋转大约 180 度,因为这个调用链的底部实际上是堆栈的顶部。

  • x方法(5)
    • x方法(4)
      • x方法(3)
        • x方法(2)
          • x方法(1)
            • x方法(0)

在递归调用中,您有两种情况 - 基本情况和递归情况。这里的基本情况是 when n == 0,并且不会发生进一步的递归。

现在,当我们开始从这些电话中回来时会发生什么?也就是说,递归步骤之后会发生什么?我们开始做System.out.print()。由于有一个条件阻止递归打印 when n == 0,我们既不递归也不打印。

因此,您获得1 2 3 4 5输出的原因是由于调用从堆栈中弹出的方式。

于 2013-04-11T06:17:28.143 回答
3

它首先以递归方式调用自身,并且只有在递归调用完成时才会打印。所以想想哪个调用首先完成 - 它是当 n = 0 时。然后是 n = 1,等等。

它是一个堆栈,您在从堆栈中取出后打印(在递归调用之后),所以顺序是相反的。如果您在放入堆栈之前打印,则保留顺序。

于 2013-04-11T06:12:07.320 回答
2
System.out.print(n + " ");
xMethod(n-1);

它将打印 5 4 3 2 1。因为它将首先打印然后调用 xMethod。

在你的情况下

xMethod(n-1);
System.out.print(n + " ");

在这里它将达到结束条件,然后弹出并打印。所以 1 2 3 4 5

于 2013-04-11T06:12:15.127 回答
2

为了解释递归是如何工作的,让我们看一下阶乘计算的示例:

int factorial(int i) {
    if (i == 0) {
        return 1;
    }
    return i * factorial(i - 1);
}

例如,让我们得到 5 的阶乘值:

int result = factorial(5);

记住退出值:

if (i == 0) {
   return 1;
}

和返回值:

i * factorial(i - 1)

只看迭代(根据返回值):

5*factorial(4) -> 4*factorial(3) -> 3*factorial(2) -> 2*factorial(1) -> 1*factorial(0)

事实上它是:

5*(4*(3*(2*(1*factorial(0)))))

原因factorial(4) == 4*factorial(3), factorial(3) == 3*factorial(2)

最后一次迭代是factorial(0)等于1(查看退出值)。

结果:

5*(4*(3*(2*(1*1)))) = 120
于 2015-12-10T10:19:51.757 回答
1

xMethod被称为直到nis 0。然后堆栈将是xMethod(5)->xMethod(4)->xMethod(3)->xMethod(2)->xMethod(1)->xMethod(0)。完成xMethod(0)后,它将弹出到下一行xMethod(1),打印1。然后这将重复,直到xMethod(5)退出。

如果您xMethod在调用每个函数时对其进行扩展,代码将如下所示:

{
    nA = 5 // What n was set at first
    if (nA>0){
        { 
            // Instead of xMethod(n-1), 
            // we're setting nB to nA - 1 and 
            // running through it again.
            nB = nA - 1  // nB is 4

            if (nB>0){
                { 
                    nC = nB - 1 // nC is 3
                    if (nC>0){
                        { 
                            nD = nC - 1 // nD is 2
                            if (nD>0){
                                {
                                    nE = nD - 1 // nE is 1
                                    if (nE>0){
                                        {
                                            nF = nE - 1 // nF is 0.
                                            if (nF>0){
                                                // This will never execute b/c nF is 0.
                                            }
                                        }
                                        System.out.print(nE + " "); // prints 1
                                    }
                                }
                                System.out.print(nD + " "); // prints 2
                            }
                        }
                        System.out.print(nC + " "); // prints 3
                    }
                }
                System.out.print(nB + " "); //prints 4 
            }
        }
        System.out.print(nA + " "); //prints 5
    }
}
于 2013-04-11T06:14:08.600 回答
0
   1 public static void xMethod(int n){
   2    if (n>0){ //the base condition
   3         xMethod(n-1); //function is again called with one value less than previous
   4         System.out.print(n + " "); //now print
   5     }
   6  }

现在看第 3 行,由于没有打印任何内容,但再次调用了该函数,因此从第 3 行开始,调用再次到达第 1 行。这意味着,n 是 5,但新调用需要 n = 4,并且它一直持续到第 2 行告诉 n 现在小于 0。

当 if 条件在第 2 行失败时,它到达第 5 行,然后到达第 6 行,这意味着函数已经结束执行,此时 n = 1。

现在应该在哪里返回呼叫?在调用最后一个函数的第 3 行,它将从执行第 4 行的堆栈中弹出,该行打印 n 的值,即 1 2 3 4 5。

于 2013-04-11T06:14:56.343 回答
-1

这个 xMethod(n-1); System.out.print(n + " ");

应该:

        System.out.print(n + " ");
        xMethod(n-1);
于 2013-04-11T06:13:13.737 回答
-2

这是正确的代码

System.out.print(n + " ");
xMethod(n-1);
于 2013-04-11T06:11:09.737 回答