【问题标题】:Why does the fibonacci recursive sequence work?为什么斐波那契递归序列有效?
【发布时间】:2016-02-25 02:53:03
【问题描述】:

我想知道为什么这个斐波那契递归函数有效:

int fibRec(int n)
{
    if ((n == 1) || (n == 0))
    {
        return n;
    }

    int i = fibRec(n - 1) + fibRec(n - 2);
    return i;
}

我了解斐波那契数列是什么,我了解递归函数的作用以及该函数的工作原理。我只是难以理解 为什么 它有效。我知道当你分解它时,你实际上是在添加一堆 0 和 1,如图所示。

fibonacci recursive

但是为什么当我将 5 传递给函数并添加所有 0 和 1 时,它将等于斐波那契数列中的第 5 个序列号?我以前见过这个问题,但从未真正解释过。响应都只是“因为递归”。是的,我知道什么是递归函数以及它是如何工作的。但是为什么这个递归函数会给你正确的斐波那契数列呢?

【问题讨论】:

  • 如果您使用节点返回的结果注释 fib(n) 节点,可能会有所帮助;或者,如果您完全在纸上计算出 fib(5)。另一种看待它的方式是:那些精心构造的(!)0和1的总和导致fib-5,因为这就是fib-5的最终定义方式;类似于“1”和“2”之和被定义为“3”。

标签: function recursion fibonacci


【解决方案1】:

在斐波那契数列中,前两个数字是零和一。这些后面的每个数字都是前两个数字的总和。所以前几个数字是

F(0) ≡ 0
F(1) ≡ 1
F(2) = F(1) + F(0) = 1 + 0 = 1
F(3) = F(2) + F(1) = 1 + 1 = 2
F(4) = F(3) + F(2) = 2 + 1 = 3
F(5) = F(4) + F(3) = 3 + 2 = 5
F(6) = F(5) + F(4) = 5 + 3 = 8
...
F(n) = F(n - 1) + F(n - 2) ∀ n > 1

因此,当我们递归计算斐波那契数时,我们必须练习以下逻辑过程(出于对 StackOverflow 的考虑,使用伪代码)。

Integer NthFibonacci(Integer n) {
    if (n < 0) {
        return undefined;
    } else if (n < 2) {
        return n;
    } else {
        return NthFibonacci(n - 1) + NthFibonacci(n - 2);
    }
}

我相信你知道这一切,但我认为将这部分作为参考将有助于我的解释。

1 和 0 的来源

最好的解释方式可能是举个例子。

想象一下,如上所述,我们正尝试递归地计算F(6)。尝试按照上面给出的过程。请记住,只有当 n > 1 时,我们才会执行递归。

首先我们从F(6) = F(5) + F(4) 开始。
然后我们找到F(5) = F(4) + F(3)
然后我们找到F(4) = F(3) + F(2)
然后我们找到F(3) = F(2) + F(1)
然后我们找到F(2) = F(1) + F(0)

这就是事情的开始!

我们现在得到了F(1) ≡ 1F(0) ≡ 0F(2)(两者都是已知的),因此我们能够计算一个实际值而不是执行更多的递归。

我们现在可以找到F(2) = F(1) + F(0) = 1 + 0 = 1

注意 1 和 0 当人们说整个事情归结为 1 和 0 时,他们就是在谈论这些。每次我们递归找到一个基值时,我们最终都会找到F(2) = 1 + 0。这会导致更多的 1 和 0,因为我们向后移动递归树,能够计算越来越高的值,如下所示。

F(3) = F(2) + F(1) = (1 + 0) + 1
F(4) = F(3) + F(2) = ((1 + 0) + 1) + (1 + 0)
F(5) = F(4) + F(3) = (((1 + 0) + 1) + (1 + 0)) + ((1 + 0) + 1)
F(6) = F(5) + F(4) = ((((1 + 0) + 1) + (1 + 0)) + ((1 + 0) + 1)) + (((1 + 0) + 1) + (1 + 0))

现在如果你把所有的 1 相加,你会得到 8,所以F(6) = 8,这是正确的!

这是它的工作原理,也是它分解为 1 和 0 的方式。

【讨论】:

  • 非常感谢!!它终于点击了。我正在查看您为每个 F(n) 提供的细分,然后它才慢慢开始变得有意义。了解 F(0) 和 F(1) 是集合数,以及之后的所有内容都是通过添加前两个数得出的,这一点至关重要。我什至通过 F(0) = 5 和 F(1) = 6 制作了自己的序列,并且能够预测输出。再次感谢您!
  • @Burt 没问题!乐于助人。
【解决方案2】:

请记住,递归的工作原理是分解问题直到我们知道答案是什么,然后从那里开始构建它。

我们对斐波那契数列了解多少?

我们知道当:

x = 1 和 x = 0

这是最低的。这是一个重要的关键。因为当 x = 0 时,我们实际上是在做 0 + 0,而当 x = 1 时,我们实际上是在做 0 + 1。现在从顶部开始。

0,1,1,2,3,5,8,13...

如果我们是 13,那么 13 是多少?为什么简单地 5 + 8 对?所以这就是

int i = fibRec(n - 1) + fibRec(n - 2);

来自。因为这些会越来越低,直到我们达到每一个的基本情况。

这是递归调用。因为现在该方法将返回堆栈并再次调用 fibRec。您会注意到 (n-1) 和 (n-2) 都加在一起并设置为 i。这样我们就不会失去价值。由于 + 符号,堆栈最终会返回越来越多的 (n-1)s 和 (n-2)s,直到我们处于基本情况。我希望所有这些都是有道理的。递归思考可能非常困难。这是从上到下的视觉表示。

简而言之。这只是不断将之前的斐波那契序列添加到当前的序列中,直到它到达当前循环。

【讨论】:

    猜你喜欢
    • 2010-12-03
    • 2011-07-27
    • 2021-04-18
    • 2014-04-02
    • 2012-11-19
    • 2016-11-07
    • 2012-02-16
    • 1970-01-01
    相关资源
    最近更新 更多