由于第二次递归调用,我无法看到程序的执行方式。解决这个问题的最简单方法是什么?
public class Recursion
{
public static void main(String[] args)
{
f(3);
}
public static void f(int x)
{
if(x>0)
{
System.out.println(x + "top");
f(x-1);
System.out.println(x + "bottom");
f(x-1);
}
System.out.println("bert");
}
}
答案 0 :(得分:3)
最后,将构建以下树:
\
/\
/ \
/\ /\
/\/\/\/\
将每个分支点视为对具有特定值的f()
的调用(3是第一个分支点,下一个向下是2,然后是1,然后是0)。
逐步:
第一个调用f(3)是顶部的一行。
\
下一个通话是f(2)
:
\
/
/
下一个通话是f(1)
:
\
/
/
/
下一个通话是f(0)
:
\
/
/
/
/
然后控件返回上一层,下一个调用再次为f(0)
:
\
/
/
/
/\
以此类推:
\
/
/
/\
/\
\
/
/
/\
/\/
\
/
/
/\
/\/\
然后图案在另一侧重复。
答案 1 :(得分:1)
它的执行方式与单个递归方法相同。让我们分解一下:
if(x>0) //x == 3
{
System.out.println(x + "top");
f(x-1); //Passes in 2
//---------- Break 1
System.out.println(x + "bottom");
f(x-1);
}
它命中了递归调用并转到:
if(x>0) //x == 2
{
System.out.println(x + "top");
f(x-1); //passes in 1
//------- Break 2
System.out.println(x + "bottom");
f(x-1);
}
再次:
if(x>0) //x == 1
{
System.out.println(x + "top");
f(x-1); //Passes in 0
//----------- Break 3
System.out.println(x + "bottom");
f(x-1);
}
然后在下一个递归调用中击中基本情况,因此它不输入if并打印bert
,然后退出该方法。
然后递归调用返回给调用者,该调用者处于中断3:
if(x>0) //x == 1
{
System.out.println(x + "top");
f(x-1); //Passes in 0
//----------- Break 3
System.out.println(x + "bottom");
f(x-1);
//---------- Break 4
}
因此,它随后命中了第二个递归调用,并传入0
。这将击中基本情况并停止递归。
然后,该方法将返回到中断4的调用方。这将终止该方法,因此它将返回到中断2的该方法的调用方。
if(x>0) //x == 2
{
System.out.println(x + "top");
f(x-1); //passes in 1
//------- Break 2
System.out.println(x + "bottom");
f(x-1);
}
然后第二个递归调用将被命中并传入x == 1
,与上面的情况相同,因此我不再重复。然后返回到调用它的方法,即中断1。然后,该方法调用第二个递归调用,即x == 2
,这也是重复。
答案 2 :(得分:0)
要可视化此代码的调用图,您需要绘制一棵树。每个内部节点都有2个子节点。
可视化调用图的另一种方法是在方法中添加一个称为缩进的字符串参数。每条输出行都将缩进,并且在每次递归调用中,缩进都将变长一点。
public static void f(String indentation, int x) {
if (x > 0) {
System.out.println(indentation + "first");
f(indentation + "....", x - 1);
…
}
}
答案 3 :(得分:0)