递归输出歧义

时间:2011-07-29 02:10:35

标签: java

好的,所以我只是在学习递归,我对一点感到困惑。 这是代码

public class RecursiveDemo {
  public static void showRecursion (int num) {
   System.out.println("Entering method. num = " + num);
    if (num > 1) {
      showRecursion(num - 1);
    }
    System.out.println("Leaving method. num = " + num);
  }

  public static void main(String[] args){
    showRecursion(2);
  }
}

我得到的输出是:

Entering method. num = 2
Entering method. num = 1
Leaving method. num = 1
Leaving method. num = 2

我的问题是为什么我得到输出“Leaving method. num = 2”。不应该停在“Leaving method. num = 1”,因为num已经达到1?

8 个答案:

答案 0 :(得分:7)

一旦该方法的原始调用离开if语句,它就会传递给System.out.println("Leaving method. num = " + num);。由于您最初使用值2调用了邮件,因此2是此部分代码的num值。

您的代码运行方式如此(伪代码):

Start First Call
    if statement
       Start Second call
           Skips if statement
           Print from Second Call
       End of Second Call
    End of if Statement
    Print From First Call
End of First Call

看起来你对递归有一个基本的误解。 当您使用(num-1)作为参数调用方法时,父调用(在本例中为第一次调用)保留值num作为其参数,在此情况下为2

答案 1 :(得分:6)

所以让我们注释下面的一行

//showRecursion(num - 1);

你会得到什么?一定是

 Entering method. num = 2
 Leaving method. num = 2

如果您取消注释上面的行。你应该得到你拥有的那个。

答案 2 :(得分:4)

没有

main会拨打showRecursion(2),然后拨打showRecursion(1)(这样您就会收到两封“输入”消息)。此时,条件将失败,因此不再发生递归。所以现在程序只是依次从每个函数调用开始返回,打印两个“Leaving”消息。

答案 3 :(得分:3)

这是因为对showRecursion(2)的初始调用尚未完成。

答案 4 :(得分:3)

请考虑以下事项:

public static void showFirstRecursion (int num) {
  System.out.println("Entering method. num = " + num);
  if (num > 1) {
    showSecondRecursion(num - 1);
  }
  System.out.println("Leaving method. num = " + num);
}

public static void showSecondRecursion (int num) {
  System.out.println("Entering method. num = " + num);
  if (num > 1) {
    showThirdRecursion(num - 1);
  }
  System.out.println("Leaving method. num = " + num);
}

// I won't bother showing an implementation for showThirdRecursion, because it won't be called.

public static void main(String[] args){
  showFirstRecursion(2);
}

这里没问题吧?您希望看到输入的第一个方法,第二个输入,(第三个未输入,因为num == 0),第二个左侧,第一个左侧。

关于递归,真的没什么特别的。它只是进行函数调用发生来调用该调用所属的函数。从概念上讲,递归调用在所有方面都像任何其他函数调用一样。诀窍是递归算法设计,即提出一个理由为什么你想要调用相同的函数''已经进入。

答案 5 :(得分:1)

其他答案已涵盖具体问题,但here是有关使用调试器的一些信息。本教程适用于Eclipse,但几乎可以告诉您需要了解的任何可视化调试器。

基础知识非常简单,至少可以学习如何逐步完成代码。调试器是一个非常有用的工具,可以快速验证程序的逻辑,并且比在任何地方散布打印语句容易得多。

答案 6 :(得分:1)

尝试“showRecursion(5);”。

[答案:这是递归。内存中有多个变量“num”的副本。 “num”是一个参数;它不是一个领域,它不是静态的。]

答案 7 :(得分:0)

所以我理解的是 随着每个方法调用,Stack都会被填充,即。 2,1 但是当i> 1不匹配时,它返回/中断调用并且控制权被赋予system.out.println行,该行打印从栈顶开始的值,即1,2