这是我的AP计算机科学课程中的示例程序,我无法理解它的控制流程。
public static void mystery( int n )
{
System.out.println( "mystery called with n = " + n );
if ( n == 0 )
{
System.out.println( "n is zero so no more recursive calls!" );
return;
}
mystery( n - 1 );
System.out.println( "We did it again with n = " + n );
}
public static void main( String[] args )
{
mystery( 5 );
}
输出:
mystery called with n = 5
mystery called with n = 4
mystery called with n = 3
mystery called with n = 2
mystery called with n = 1
mystery called with n = 0
n is zero so no more recursive calls!
We did it again with n = 1
We did it again with n = 2
We did it again with n = 3
We did it again with n = 4
We did it again with n = 5
到目前为止,我理解递归方法以及它如何通过以下方式回忆起来:
mystery( n - 1 );
但是,在以下情况之后,我不知道如何输出这五个声明:
n is zero so no more recursive calls!
从逻辑上讲,它似乎只会说明:
We did it again with n = 0
任何人都可以帮助学生并向我解释它是如何输出的吗?
答案 0 :(得分:4)
当函数完成时,调用它的函数有机会完成并执行更多代码。
以下是此递归如何发生的说明。 每个递归级别由缩进的增加表示。
mystery(5):
"mystery called with n = 5"
mystery(4):
"mystery called with n = 4"
mystery(3):
"mystery called with n = 3"
mystery(2):
"mystery called with n = 2"
mystery(1):
"mystery called with n = 1"
mystery(0):
"mystery called with n = 0"
"n is zero so no more recursive calls!"
mystery(0) returns
"We did it again with n = 1"
end of mystery(1)
"We did it again with n = 2"
end of mystery(2)
"We did it again with n = 3"
end of mystery(3)
"We did it again with n = 4"
end of mystery(4)
"We did it again with n = 5"
end of mystery(5)
答案 1 :(得分:2)
'n为零之后不再有递归调用!'方法继续(状态被放在堆栈上,然后在方法(n-1)的调用结束后加载。
答案 2 :(得分:1)
这是一种考虑递归程序的好方法:当你阅读程序的代码时,假装你知道程序的功能,即使你还不知道它。在您的情况下,这将是这样的:
n == 0
,则打印固定消息 - 这是no more recursive calls!
字符串n != 0
,则打印n
,然后打印n-1
打印的任何程序,然后再打印n
- 换句话说,对于n-1
以下是这样:
mystery called with n = <something>
... whatever the program prints in between...
We did it again with n = <something>
在进入呼叫的递归部分之前,第一次打印输出; 从递归部分返回后,发生了最后一次打印输出。请注意,<something>
在顶部和底部是相同的,因为n
的值存储在每个堆栈帧上,并在递归展开时设置为先前的值。
有了这张图片,很容易看到你继续添加嵌套的“框架”,直到你点击n==0
,此时你在中间打印信息。
答案 3 :(得分:0)
通过神秘方法的前五次,该方法不会停止在递归调用。它继续,输出“我们再次做到了”。但我想,因为神秘是阻塞,所以只有在返回最后一次递归调用后才允许该方法完成。因此,当打到n = 0时,前五个调用继续到他们原来的结论,打印“我们再次使用n = ...”
答案 4 :(得分:0)
以下是这个递归方法的用法:
mystery(5): {
| println( "mystery called with n = 5" );
|
| n != 0:
| skip return
|
| mystery(n - 1) is mystery(4)
|
| call mystery(4): {
| | println( "mystery called with n = 4" );
| |
| | n != 0:
| | skip return
| |
| | mystery(n - 1) is mystery(3)
| |
| | call mystery(3): {
| | | println( "mystery called with n = 3" );
| | |
| | | n != 0:
| | | skip return
| | |
| | | mystery(n - 1) is mystery(2);
| | |
| | | call mystery(2): {
| | | | println( "mystery called with n = 2" );
| | | |
| | | | n != 0:
| | | | skip return
| | | |
| | | | mystery(n - 1) is mystery(1);
| | | |
| | | | call mystery(1): {
| | | | | println( "mystery called with n = 1" );
| | | | |
| | | | | n != 0:
| | | | | skip return
| | | | |
| | | | | mystery(n - 1) is mystery(0);
| | | | |
| | | | | call mystery(0): {
| | | | | | println( "mystery called with n = 0" );
| | | | | |
| | | | | | n == 0:
| | | | | | return from mystery(0)
| | | | | }
| | | | |
| | | | | back inside mystery(1), continue executing where we left off
| | | | | println("We did it again with n = 1")
| | | | | method ends; return to caller
| | | | }
| | | |
| | | | back inside mystery(2), continue executing where we left off
| | | | println("We did it again with n = 2")
| | | | method ends; return to caller
| | | }
| | |
| | | back inside mystery(3), continue executing where we left off
| | | println("We did it again with n = 3")
| | | method ends; return to caller
| | }
| |
| | back inside mystery(4), continue executing where we left off
| | println("We did it again with n = 4")
| | method ends; return to caller
| }
|
| back inside mystery(5), continue executing where we left off
| println("We did it again with n = 5")
| method ends; program ends
}