当前位置: 首页 > 知识库问答 >
问题:

这个递归斐波那契的Big-O时间复杂度?

鲁德佑
2023-03-14

我有一个使用递归打印斐波那契级数的程序。有更好的方法,但我被要求使用递归,所以我不得不这样做。

这是程序:

#include <stdio.h>
#define TERMS 10

long fibo(int);

int main(void){
   for(int i = 1; i <= TERMS; i++) {
       printf("%ld", fibo(i));
   }
   return 0;
}

long fibo(int n){
    if (n < 3) {
        return 1;
    }
    else {
        return fibo(n - 1) + fibo(n - 2);
    }
}

我知道这对于斐波那契级数来说真的是一种糟糕的方法,从上面可以清楚地看出,当项超过35时,程序需要很多时间才能完成。

我看了这个答案,不明白他们是怎么解决的,但看起来

fibo(int n)的时间复杂度为O(2^n)

我可能完全错了,但我只想:

这个完整程序的时间复杂度是多少,简要解释一下您是如何计算的?

如果您有更好的方法使用递归计算斐波那契,也欢迎使用。

共有3个答案

韦泳
2023-03-14

产生斐波那契级数的递归函数生成一棵高度为n的二叉树。假设我们取n=5。那么树结构将是这样的:

在最底层,我们将最终得到大约2^n个节点。因此时间复杂度将在O(2^n)左右,因为递归将对每个叶节点重复。

我们可以通过使用记忆的动态规划方法大大改进这一点,该方法基本上是将重复子问题(例如示例中的fib(2)fib(3))存储在某种查找表中。这将时间复杂度降低到O(n)。

满勇军
2023-03-14

一般来说,它背后有数学,斐波那契在这里解释:https://en.wikipedia.org/wiki/Recurrence_relation

如果你不需要证明它,只需要正确地写下来,你只需要考虑算法的行为,以及一些数字会有多少次重复,然后你可以尝试将其推广到任何输入。

纸是你的朋友!

如果在递归中有值为“10”的斐波那契,基本上就是说(10的斐波那契是9的斐波那契,8的斐波那契)

然后你们说斐波那契9,它是斐波那契8,斐波那契7等等。

你可以画一个图表:

我认为很明显,它将延续到几乎完整的二叉树。您可以看到,对于每个级别,节点数量都会增加一倍,因此对于fib(10),它将重复10次,底部几乎是2^10,因此对于fib(n),它将是2^n

如何使其在递归alghoritm中有效?从图中可以看出,fib(7)求解了三次。所以你必须记住fib(n),一旦你计算了它。它可以是全局变量,也可以通过递归调用传递对对象的引用。

然后你不只是说“fib(n-1)和fib(n-2)”,你首先看“fib(n-1)被计算了吗?”?如果是这样,则使用计算值而不是递归。

后星河
2023-03-14

c(fibo(n))=c(fibo(n-1))c(fibo(n-2))O(1)

注意,由于所有计算分支始终以值为1的叶结束,因此复杂度遵循级数的精确公式,因此精确(θ)复杂度可以通过斐波那契级数本身的闭合公式精确计算

但这超出了你的问题范围,我们需要注意的是

c(fibo(n))

我们现在只需要求解由定义的上界级数

an=2*an-1(a1,2=1)

结果在

an=2^n

因此,得到了想要的2^n的上界O。

如果你运行几次,你会得到

σ(c(fib(n)))从1到项=O(2^(项1)-1)

这是一个简单的数学事实,这意味着在你的情况下(TERMS=10)你得到

2^11 - 1 = 2047

至于你的问题,关于一种更好的递归方式。。。

int fib(int n, int val = 1, int prev = 0)
{
    if (n == 0) {
        return prev;
    }
    if (n == 1) {
        return val;
    }
    return fib(n - 1, val + prev, val);
}

这就是所谓的尾部递归,需要O(n)(事实上,它可以由一个好的编译器优化,以实现为循环,然后还将消耗恒定的内存消耗)

 类似资料:
  • 问题内容: 我在大学为我的Programming II类编写的程序需要一些帮助。这个问题要求人们使用递归来计算斐波那契数列。必须将计算出的斐波那契数存储在一个数组中,以停止不必要的重复计算并减少计算时间。 我设法使程序在没有数组和存储的情况下运行,现在我试图实现该功能,但遇到了麻烦。我不确定如何组织它。我已经浏览了Google并浏览了一些书,但没有太多帮助我解决如何实施解决方案的方法。 上面是不正

  • 问题内容: 请解释以下简单代码: 我对最后一行感到困惑,特别是因为例如,如果n = 5,则将调用fibonacci(4)+ fibonacci(3),依此类推,但我不理解该算法如何以此来计算索引5的值方法。请详细解释! 问题答案: 在斐波那契数列中,每一项都是前两项的总和。因此,你编写了一个递归算法。 所以, 现在你已经知道了。因此,你可以随后计算其他值。 现在, 从斐波那契数列中我们可以看到斐波

  • 我试图想出一个程序,从用户那里获取任何数字,并生成斐波那契码的第n个数字。当我完成工作时,它会显示下一个,而不是我需要的。例如,我正在寻找第11个#和它的生产233而不是144。这是我的代码:

  • 本文向大家介绍Java递归实现斐波那契数列,包括了Java递归实现斐波那契数列的使用技巧和注意事项,需要的朋友参考一下 程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所

  • 我有两种不同的方法,一种是用迭代法计算第n个元素的斐波那契序列,另一种是用递归法。 程序示例如下所示: 我试图找出哪种方法更快。我得出的结论是,对于较小数量的数字,递归速度更快,但随着第n个元素的值增加,递归速度变慢,迭代速度变快。以下是三个不同n的三个不同结果: 示例#1(n=10) 示例#2(n=20) 示例#3(n=30) 我真正想知道的是,为什么迭代突然变得更快,递归变得更慢。如果我错过了

  • Python3 实例 以下代码使用递归的方式来生成斐波那契数列: 实例(Python 3.0+)# Filename : test.py # author by : www.runoob.com def recur_fibo(n): """递归函数 输出斐波那契数列""" if n <= 1: return n else: return(recur_fibo(n-1) + recur_fibo(n