c - 为什么递归需要这么长时间?

标签 c

在使用递归计算斐波那契数列的第n个数时,我写了这个简单的程序:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

unsigned int long long fibonacci(unsigned int number);

//game of craps
int main(int argc, char** argv)
{

    for(int n = 1; n <= 100; n++)
    {
        printf("%llu\n", fibonacci(n));
    }

    return (EXIT_SUCCESS);
}


unsigned long long int fibonacci(unsigned int number)
{
    if (number == 0 || number == 1)
    {
        return number;
    }
    else
    {
        return fibonacci(number - 2) + fibonacci(number - 1);      
    }
}

其中每次调用序列中的 n+1 数字都会使程序必须运行的函数调用次数加倍。因此,对递归函数的调用次数是 2^n,或指数复杂度。明白了。但是所有的计算能力都去了哪里呢?一旦序列中的第 n 个数字开始达到 40,计算机开始花费大量时间来计算结果,在 n = 47 时需要 30 多秒。但是我的电脑显示我只使用了 21% 的 CPU 功率。我正在使用 NetBeans IDE 来运行该程序。这是一个四核系统。

最佳答案

the number of calls being made to the recursive function is something of 2^n, or exponential complexity. Understood.

我不确定您是否完全理解这一点,因为您似乎对它在 n=40 和 n=47 时变得如此缓慢感到惊讶。

如果复杂度为 2^n,n 为 40,则为 240,或 1,099,511,627,776,或大约 1 万亿 操作。如果您的计算机每纳秒可以运行其中一个操作,即每秒 10 亿次操作,则需要 1000 秒才能完成。

考虑一下 n 是否只有 30。230 是 1,073,741,824,这在同一台计算机上只需要大约 1 秒。

如前所述,您只使用了一个内核。您可以并行化,但这无济于事。使用四个内核而不是一个内核,我的 n=40 示例仍然需要 250 秒。上升到 n=42,你又回到了 1000 秒,因为并行化充其量会使你的性能成倍增加,但像这样的算法呈指数级增长。

关于c - 为什么递归需要这么长时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46081271/

相关文章:

c - c中的函数命名约定修饰/重载

c - 如何使用作为参数传递给 lua C 函数的表?

c - 如何制作下载其较新副本的二进制文件?(有限条件)

objective-c - oc中_xxx和self->_xxx有什么区别

c++ - C++ 中树数据结构在现实生活中的使用示例?

C 共享内存读写器段错误

c - 如何对 char 字符串/数组使用 malloc() 函数?

c - 如何使用 makefile 来测试我的 shell 实现?

c - 在这些声明下,以下表达式是什么类型,它们是否正确?

c - 解释来自 apr_dso_load() 的错误代码