Java - 理解递归

时间:2013-04-11 06:09:32

标签: java recursion

有人可以向我解释为什么打印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 + " ");
        }
    }


}

9 个答案:

答案 0 :(得分:18)

这很简单,这些是电话

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

答案 1 :(得分:5)

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

  • xMethod(5)
    • xMethod(4)
      • xMethod(3)
        • xMethod(2)
          • xMethod(1)
            • xMethod(0)

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

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

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

答案 2 :(得分:3)

它首先以递归方式调用自身,并且仅在递归调用完成时才打印。 所以考虑哪个调用首先完成 - 当n = 0时。 那么n = 1,等等。

它是一个堆栈,你从堆栈中取出后(在递归调用之后)打印,所以顺序颠倒了。 如果在放入堆叠之前打印,则会保留订单。

答案 3 :(得分: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

答案 4 :(得分: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

答案 5 :(得分:1)

xMethodn之前调用

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

答案 6 :(得分: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。

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

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

答案 7 :(得分:-1)

此             xMethod第(n-1);             System.out.print(n +“”);

应该是:

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

答案 8 :(得分:-2)

这是正确的代码

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