2016-08-23 701 views
2

我正在阅读一本名为“Think Java:如何像计算机科学家一样思考”的书,最近我介绍了递归方法。逆向递归java方法

public static void countdown(int n) 
{ 
    if (n == 0) { 
     System.out.println("Blastoff!"); 
    } else { 
     System.out.println(n); 
     countdown(n - 1); 
    } 
} 

这将是用来降低到0计数正常的递归方法,我明白发生了什么,但如果你做递归调用之前的System.out.println这样

public static void countdown(int n) 
{ 
    if (n == 0) { 
     System.out.println("Blastoff!"); 
    } else { 
     countdown(n - 1); 
     System.out.println(n); 
    } 
} 

它的计数方式是相反的,所以如果我为这两个条件陈述给出了论点3,那么第一个就是“3,2,1,Blastoff!”但第二个1会出现“Blastoff,1,2,3”....我不明白这是如何工作的,有人可以试着解释在这段代码中发生了什么,它会以相反的方式进行计数?

+0

为了更好地理解它是如何工作,把println的是第一种方法行。 – RominaV

回答

0

它不算“相反的方式”,它只是按照您可能没有预料到的顺序“解开”。尝试写出你期望发生的事情,我会很乐意帮助解决这种误解。

+0

1秒让我写出来并编辑这个WTF?为什么我不能在不保存的情况下输入 –

+0

在第二个函数中,递归调用发生在* println之前,因此首先达到基本情况(当n == 0时为真)。然后它返回,到达前一个调用的'println'并打印'3',然后返回等等。 – EntangledLoops

+0

编辑:感谢清除那个,我明白它是如何调用倒计时并跳过System.out.println,只有怪异的对我而言,n是等于0之后的递归调用继续计数。 –

0

问题在于打印行将等到您的函数调用完成。因此它会在到达第一个打印线之前连续调用该函数3次

0

递归的要点是每一步都有自己的“栈帧”,它有自己的局部变量,它记住了。

因此,即使在一次迭代中更改n,调用此迭代的函数仍将保留其自己的值n。当需要打印这个n时,它仍然是原始值(比下一次迭代中的值大)。

4

认为它这样......在第一种情况下,你将总是先下去下一功能打印,所以......

countdown(3) 
    System.out.println(3) 
    countdown(2) 
    System.out.println(2) 
    countdown(1)  
     System.out.println(1) 
     countdown(0) 
     System.out.println("Blastoff") 

结果:3 2 1升空

在第二种情况,是因为你先打印出来,你的运行将一路走下来递归直到基本情况开始打印......

countdown(3) 
    countdown(2) 
    countdown(1) 
     countdown(0) 
     System.out.println("Blastoff") 
    System.out.println(1) 
    System.out.println(2) 
System.out.println(1) 

结果:1 2 3升空

递归很难!我希望我帮助:)

9

我会尽量为你想象它。

第一种方法

countdown(3)    (first call) 
"3"       (sysout) 
    countdown(3-1)   (second call) 
    "2"      (sysout) 
     countdown(2-1)  (third call) 
     "1"     (sysout) 
      countdown(1-1) (fourth call) 
       "Blastoff!" (n == 0) 

方法二

countdown(3)    (first call) 
    countdown(3-1)   (second call) 
     countdown(2-1)  (third call) 
      countdown(1-1) (fourth call) 
       "Blastoff!" (n == 0. going back up call stack) 
      "1"    (sysout) 
     "2"     (sysout) 
    "3"      (sysout)