在此程序中,如果用户输入数字3,则o / p将为3 2 1 1 2 3,我知道3 2 1是怎么来的,但是我不知道1 2 3到底是怎么来的。
{{1}}
答案 0 :(得分:4)
一种通过递归函数进行跟踪的方法是扩展每个递归调用,例如数学表达式。
首先我们开始
printFun(3)
它扩展为:
print(3) // I have shortened System.out.printf here to just "print" to remove the noise
printFun(2)
print(3)
我们还有一个递归调用(printFun(2)
),所以让我们扩展一下。
print(3)
print(2)
printFun(1)
print(2)
print(3)
继续扩展:
print(3)
print(2)
print(1)
printFun(0)
print(1)
print(2)
print(3)
最后一次(由于printFun(0)
不执行任何操作,因此我们将其删除):
print(3)
print(2)
print(1)
print(1)
print(2)
print(3)
哦,看!这将产生输出3 2 1 1 2 3
!
答案 1 :(得分:3)
好-递归的性质。递归将他们的调用放在自底向上构建的堆栈上。每当从堆栈中召回成员时,都应从顶部开始,直到我们再次到达底部为止。让我们逐行浏览它:
函数第一次被3调用
函数写入:3并以2调用自身-函数暂停(在statement2之后)并等待执行
函数写入:2并以1调用自身-函数停止并等待执行
函数写道:1并用0调用自身-调用由于值0而立即返回。减少调用者堆栈并继续暂停函数的时间。
最后一个函数暂停被重新激活(它是1)并写:1-然后函数返回
最后一个函数暂停被重新激活(它是2)并输入:2-然后函数返回
最后一个功能暂停被重新激活(为3)并输入:3-然后功能返回
程序停止。
因此,您得到的是所写的数字行。
答案 2 :(得分:3)
递归调用printFun(test-1)
使方法继续以这种方式调用它:
printFun(3); // original
printFun(2);
printFun(1);
printFun(0);
由于printFun(0)
遇到的情况,此时到达它不会执行任何其他递归调用。
作为最后一个递归调用(printFun(0)
)的当前调用继续进行return
。然后执行执行到printFun(0)
的调用者,即printFun(1)
,它执行第二条System.out.printf("%d ",test);
语句,并执行returns
。
然后是相同的逻辑:执行将转到调用该方法的方法,即printFun(2)
。
直到第一次调用为止。
您可以通过这种方式查看通话:
printFun(3)
printFun(2)
printFun(1)
printFun(0)
-- No more recursive call, execution goes on where we are
printFun(0)
printFun(1)
printFun(2)
printFun(3)
答案 3 :(得分:2)
我添加了一些打印命令来帮助您理解这一点。
class GFG{
static int count = 1;
static String combined = "";
static void printFun(int test){
System.out.println("No of times Function printFun has been called : " + count);
count = count + 1;
if (test < 1)
return;
else{
System.out.println("Adding " + test + " to combined string");
combined = combined + test;
printFun(test-1); // statement 2
System.out.println("Returning to the previous call of printFun");
combined = combined + test;
System.out.println("Adding " + test + " to combined string");
return;
}
}
public static void main(String[] args){
int test = 3;
printFun(test);
System.out.println(combined);
}
}
我将在最后打印出组合的字符串,print语句应指示函数如何递归调用。
答案 4 :(得分:0)
函数调用由堆栈维护。函数的所有局部变量都对应于函数调用实例。每个函数调用实例都保存在Stack中。
以上声明,递归调用是PUSH操作,递归调用之后是POP操作。
因此 (递归调用前的声明)
print(3)PUSH(3),print(2)PUSH(2),print(1)PUSH(1)
之后 (递归调用后的声明)。
POP(1)打印(1),POP(2)打印(2),POP(3)打印(3)
因此输出为3 2 1 1 2 3