[英]How does this implementation of Fibonacci(n) work? [recursion]
我正在阅读的一本Java书籍中有一个练习让我感到困惑:
斐波那契数列是数字1、1、2、3、5、8、13、21、34等的序列,其中每个数字(从第三个数字开始)是前两个数字的和。 创建一个以整数作为参数并从头开始显示许多斐波那契数的方法。 例如,如果您运行Java Fibonacci 5(其中Fibonacci是类的名称),则输出将为:1、1、2、3、5。
我可能会发誓,它需要一个数组或某种方式来存储先前的数字,但是当我看到答案时,情况并非如此:
import java.util.*;
public class Fibonacci {
static int fib(int n) {
if (n <= 2)
return 1;
return fib(n-1) + fib(n-2);
}
public static void main(String[] args) {
// Get the max value from the command line:
int n = Integer.parseInt(args[0]);
if(n < 0) {
System.out.println("Cannot use negative numbers"); return;
}
for(int i = 1; i <= n; i++)
System.out.print(fib(i) + ", ");
}
}
有人能够解释一下如何在自身内部使用函数吗?
您提供的代码是递归解决方案的示例。 首次调用该函数时,它将执行直到调用自身。 它的状态存储在堆栈中,并且代码开始使用新的输入数据再次执行。 重复此过程,直到输入小于2,然后返回1,然后答案返回到先前的呼叫者。
例如,调用fib(5)将导致以下执行:
fib(5):
fib(4):
fib(3):
fib(2): 1
fib(1): 1
fib(2): 1
fib(3):
fib(2): 1
fib(1): 1
请注意,您部分正确。 中间结果在此解决方案中存储在堆栈中。 这就是递归解决方案如此昂贵的原因之一。 另一个是它的O(2^n)
复杂度。 但是,如果可以迭代地计算Fibonacci(n)
,而无需存储所有先前的结果。 您真正需要的只是存储最后一个结果,并从1到n
计数。
F(n)
/ \
F(n-1) F(n-2)
/ \ / \
F(n-2) F(n-3) F(n-3) F(n-4)
/ \
F(n-3) F(n-4)
需要注意的重要一点是该算法是指数算法,因为它不存储先前计算得出的数字的结果。 例如F(n-3)被调用3次。
有关更多详细信息,请参阅dasgupta的算法第0.2章
这是一个递归解决方案。 递归函数将自行调用,直到满足给定的停止条件为止。 然后,每个呼叫都退出,直到仅剩下第一个呼叫为止。 第一个调用输出结果。
在您的解决方案中,停止条件为:
if (n <= 2)
return 1;
在满足此条件之前,该函数将对其自身进行连续调用。 每次调用都会减少作为参数传递的int值。 当它达到2时,停止条件指示该函数返回值1(fibonacci(n)中n = 1和n = 2的结果)。
因为斐波那契数是最后两个数字的和,所以函数的递归部分
return fib(n-1) + fib(n-2);
进行n-1和n-2的和(如我所说,序列的最后两个数字)。 当n等于2时,这些对函数fib的调用最终将有一个值,并将被返回。
例如,如果n = 3,则递归部分将调用fib(2)和fib(1),它们都等于或小于2,因此这两个调用都将返回1。因此printf将输出1、1、2、2。 1 + 1的总和(我知道这很明显,但有时会说出明显的帮助)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.