我正在读一本名为“思考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 :(得分: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)
答案 1 :(得分: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 Blastoff
在第二种情况下,因为你先打印它,你的运行将一直向下递归,直到基本情况开始打印...
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 Blastoff
递归很难!我希望我帮助过。)
答案 2 :(得分:0)
它不算“相反的方式”,只是它按照你可能没想到的顺序“解开”。尝试写出你期望发生的事情,我很乐意帮助解决误解。
答案 3 :(得分:0)
问题是打印行将等待您的函数调用完成。因此,它会在到达第一个打印行之前连续调用该函数
答案 4 :(得分:0)
递归的整个要点是每一步都有自己的“堆栈框架”,它有自己的局部变量,它会记住它。
因此,即使您在一次迭代中更改n
,调用此迭代的函数仍将保留其自己的n
值。当打印此n
时,它仍然是原始值(比下一次迭代中的值大一个)。