我在Java中使用Recursion遇到了一些问题。 这是我的代码
public class recursionTrial {
public static void main(String[] args)
{
System.out.println(doSomething(6));
}
public static int doSomething(int n)
{
if (n==0 || n==1)
return 0;
else
return n + doSomething(n-1) + doSomething(n-2);
}
}
这给了我38的输出。但是我无法在脑中或纸上追踪递归函数。如何锻炼外观? 6 + 5 ....等等。
如果只是
我就知道了return n + doSomething(n-1)
那么它将是6 + 5 + 4 + 3 + 2 = 20;这是代码的第二部分令我感到困惑。如果有人可以向我解释如何正确地追踪递归函数并编写工作,我将不胜感激!还有一种方法可以编写一段代码,在每次更改之前打印n的值吗?
答案 0 :(得分:2)
在没有副作用的情况下,人们可以将这种递归函数视为常规函数。您可以绘制一个小表,显示函数调用的结果,从零开始:
n res computation
- --- -----------
0 0 0
1 0 0
2 2 2+0+0
3 5 3+2+0
4 11 4+5+2
5 21 5+11+5
6 38 6+21+11
第二次递归调用不需要特殊的心理处理:它与第一次递归调用相同。
注意:随着n
的值上升,您的函数将逐渐变长,因为它将重新执行已经完成的大量计算。幸运的是,这可以通过一个简单且非常常见的技巧来解决,称为memoization。
答案 1 :(得分:0)
doSomething(1)=返回0,
doSomething(2)== 2 + dosomething(1)= 2 + 0 = 2,
doSomething的(3)= 3 + doSomething的(2)= 3 + 2 = 5,
doSomething的(4)= 4 + doSomething的(3)+ doSomething的(2)= 4 + 5 + 2 = 11
doSomething的(5)= 5 + doSomething的(4)+ doSomething的(3)= 5 + 11 + 5 = 21,
doSomething的(6)= 6 + doSomething的(5)+ doSomething的(4)= 6 + 21 + 11 = 38
从doSomething(6)开始,它调用:doSomething(5)去那行,找出doSomething(5)我们需要知道doSomething(4)和doSomething(3)....并按照自己的方式工作在树上,直到你得到一个实际的"返回值"在这种情况下,当我们到达doSomething(1)时,然后将这些值放入树中。
答案 2 :(得分:0)
你的递归函数是
f(n) = n + f(n-2) + f(n-1)
执行流程如下。
例如,n = 4的递归树如下(为简单起见,我没有显示n的加法):
f(4) {
f(2) {
f(0) {0}
f(1) {0}
}
f(3) {
f(1) {0}
f(2) {
f(0) {0}
f(1) {0}
}
}
}
答案 3 :(得分:0)
public static int doSomething(int n) {
if (n==0 || n==1)
return 0;
else
return n + doSomething(n-1) + doSomething(n-2);
}
你可以尝试递归扩展,这在概念上是程序的作用。
doSomething(6)
扩展为6 + doSomething(5) + doSomething(4)
doSomething(5)
扩展为5 + doSomething(4) + doSomething(3)
doSomething(4)
扩展为4 + doSomething(3) + doSomething(2)
...
简单地下去递归。例如(我使用dS for doSomething):
dS(6) = 6 + dS(5) + dS(4) =
6 + 5 + dS(4) + dS(3) + 4 + dS(3) + dS(2) =
6 + 5 + 4 + dS(3) + dS(2) + 3 + dS(2) + dS(1) + 4 + 3 + dS(2) + dS(1) + 2 + dS(1) + dS(0) =
6 + 5 + 4 + 3 + dS(2) + dS(1) + 2 + dS(1) + dS(0) + 3 + 2 + dS(1) + dS(0) + 0 + 4 + 3 + 2 + dS(1) + dS(0) + 0 + 2 + 0 + 0 =
6 + 5 + 4 + 3 + 2 + dS(1) + dS(0) + 0 + 2 + 0 + 0 + 3 + 2 + dS(1) + 0 + 0 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 =
6 + 5 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 + 3 + 2 + 0 + 0 + 0 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 =
38 <-- Final result
答案 4 :(得分:0)
请注意,这具有指数级复杂性
doSomething(6)
来电doSomething(5)
和doSomething(4)
doSomething(5)
来电doSomething(4)
和doSomething(3)
doSomething(4)
来电doSomething(3)
和doSomething(2)
doSomething(3)
来电doSomething(2)
和doSomething(1)
doSomething(2)
来电doSomething(1)
和doSomething(0)
doSomething(1)
为0
doSomething(0)
为0
这说明了doSomething()
的来电,它们不是结果,因为您为每次通话添加了n
。
6 _______|_______ / \ 5 4 ____|____ _|_ / \ / \ 4 3 3 2 _|_ | | | / \ / \ / \ / \ 3 2 2 1 2 1 1 0 / \ / \ / \ / \ 2 1 1 0 1 0 1 0 / \ 1 0