c - 多次递归调用的时间复杂度是多少?

标签 c recursion time-complexity

谁能解释一下我们如何评估这个函数的时间复杂度?

int f(int n) 
{ 
    int x,y,z,t; 
    if(n ==1 || n==0) return n; 
    x=f(n/2); 
    y=f(n/3); 
    z=f(n/4); 
    t=x+y+z; 
    if(t<n) return n; 
    return t; 
}

最佳答案

对于像这样的非显而易见的算法,我总是喜欢对复杂性进行实际测量。您可以像这样修改您的代码:

size_t Counter = 0;

int f(int n) 
{ 
    ++Counter;
    ...

然后做一个简单的测试:

 for (int i = 0; i < 10000; ++i)
 {
     Counter = 0;
     int Result = f(i);
     printf("%d: f(%d) = %d\n", Counter, i, Result);
 }

图表是可视化数据的好方法。对于 0-10000n 函数,我们得到(蓝线是循环计数,红色是线性拟合):

enter image description here

这是一个明显的线性关系。关于此方法的一些重要注意事项:

  • 在对较大的 N 进行外推时要小心。对于复杂的算法,行为可能会发生变化,即对于较小的 N,它可能看起来是线性的,但对于较大的 N 会变成二次方(反之亦然)。如果您对 N 的所有值都需要它,那么唯一的方法就是其他答案给出的理论方法。
  • 在这种情况下,我测量了循环次数,但在某些情况下,实际测量函数调用时间作为 N 的函数可能会更好。在这种情况下,函数调用时间非常短,并且不会给出结果有意义或易于解释(至少在 0-10000 范围内)。

关于c - 多次递归调用的时间复杂度是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30258563/

相关文章:

c - POSIX 线程 : the best interruption method

c -\n 文件中 EOF 之前的字符导致问题

python - 使用递归函数处理构建字符串

java - 作业 : Magic Plant Recursion Exercise in Java

c - sqrt 函数出现小错误

java - 递归法

c++ - C++ String length() 和 size() 哪个更快?

algorithm - 在 O(V + E) 时间内在加权无向图中找到从源到目标的最短路径

java - 如何计算确定在某一点结束的无限循环的时间复杂度?

c - 如何在c中追加到指针数组