[英]Understanding how a loop of recursive calls work
我真的对恢复性很陌生,偶然发现了一个练习,在这个练习中,我们有一个循环进行多次递归调用,但我不明白它是如何工作的。
看下面的例子:
int calculateSomething (int n) {
if (n > 100)
for (int i = 0; i < 10; i++)
calculateSomething(n+1);
}
假设我第一次拨打了calculateSomething(200),我将要接多少个电话? 乍一看,我会说100 * 10,所以1000个电话?
每个呼叫是否都将“ i”提高到10? 还是调用每个“ i”值?
很抱歉提出这样的问题,但我确实阻止了XD
提前致谢 !
首先,您的示例代码将无限循环使用,因为在您的所有递归调用中if( n>100 )
都会被评估为TRUE,因为您的“ n”值始终会增加。 calculateSomething(n+1)
如果您调用calculateSomething(200)
,则第一个递归调用将在for循环内,且i=0
, CalclulateSomething(201)
然后忘了for循环的下一个迭代,直到递归调用结束为止,并且正如我之前解释的那样,它将永远不会发生。
calculateSomething(200)
-> i=0 calculateSomething(201)
-> i=0 calculateSomething(202)
-> i=0 calculateSomething(203)
-> ...infinite...
以下面的代码为例:(修复了无限循环,并减小了值进行说明)
int calculateSomething (int n) {
if (n < 3)
for (int i = 0; i < 3; i++)
calculateSomething(n+1);
}
递归调用将是:
calculateSomething(0)
-> i=0 calculateSomething(1)
-> i=0 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(1)
-> i=0 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(1)
-> i=0 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(2)
-> i=0 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=1 calculateSomething(3)
-> end. if (n < 3) = FALSE
-> i=2 calculateSomething(3)
-> end. if (n < 3) = FALSE
如果要计算函数被调用的次数,可以简单地添加一个conunter并为每个调用增加它,例如:
int counter = 0; // declaring it on a global scope
int calculateSomething (int n) {
counter++;
if (n < 3)
for (int i = 0; i < 3; i++)
calculateSomething(n+1);
}
即使返回类型为int,您所给的程序也没有return语句。 而且,由于没有结束条件,它将无限进行。
这将是执行周期
通话1:n = 200,i = 0计算方法(201次)
通话2:n = 201,i = 0calculateSomething(202)
通话3:n = 202,i = 0calculateSomething(203)...。
每个呼叫是否都将“ i”提高到10? 还是调用每个“ i”值?
调用i的每个值。 递归适用于堆栈(后进先出)。 在简单的程序中,我从main调用Method1并从Method1调用Method2,看起来像这样的堆栈
方法2
方法1
主要
基本上,最后一个调用将在顶部,一旦完成,它将转到下一个。
由于您是新手,因此从一个简单的示例(例如阶乘)开始
public static int factorial(int n) {
if (n == 0) {
return 1;
} else {
System.out.println(n + " "+ (n-1));
return n * factorial(n - 1);
}
}
如果调用factorial(3),则堆栈看起来像
1(因为阶乘(1-1),即阶乘(0)为0)
1 *阶乘(1-1)
2 *阶乘(2-1)
3 *阶乘(3-1)
factorial(3)->实际方法调用
现在,每次调用返回此处,它将用实际值替换其下面的一个因子(n-1),即
阶乘(1-1)将替换为1
阶乘(2-1)将替换为1 * 1
阶乘(3-1)将替换为2 *(1 * 1)
factorial(3)变为3 *(2 *(1 * 1))
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.