线性递归、二元递归与运行时的关系

Posted

技术标签:

【中文标题】线性递归、二元递归与运行时的关系【英文标题】:The relationship between linear recursion, binary recursion and runtime 【发布时间】:2013-05-22 17:41:22 【问题描述】:

假设我们有一个需要 n 步的方法,但在最坏的情况下它会线性调用自身 n 次。在这种情况下,大 O 会是 n*n 吗?那么递归调用通常是 n^2 类似于两个 for 循环吗?

现在让我们采用二进制递归算法,例如二进制斐波那契。该算法的 1 次调用需要 n 步,但假设它最多可以重复 n 次。该算法的运行时间会是 2^n 吗?

【问题讨论】:

这可能属于:cs.stackexchange.com 而不是这里。在致力于此类事情的社区中,您会得到更好的答案。 @ArtB 你确定吗? Stack Overflow 上有很多运行时分析问题,据我所见,Computer Science 上的问题有点多……我们应该说……困难或复杂。 【参考方案1】:

f() 是一个调用自身n 次的函数。考虑代表函数f()的C代码。

int f(int n)

  int i;
  if(n==0)
  
     printf("\n Recursion Stopped");
  
  else
  
     for(i=0;i<=n;i++)
     
        printf("\n Hello");
       
     f(n-1);
  
 

对于n = 5,消息Hello 将被打印15 次。 对于n = 10,消息Hello 将被打印55 次。

一般而言,该消息将被打印n*(n+1)/2 次。

因此函数f()的复杂度为O(n2)。请记住f() 是一个具有复杂性n 的函数,f() 被递归调用n 次。如果内部循环包含诸如加法、减法等恒定时间表达式,则此类函数的复杂度等于以下循环顺序。

for(i=0;i<=n;i++)

  for(j=i;j<=n;j++)
  
     /* Some constant time operation */
  

对于Binary Recursion,时间复杂度为 O(2n)

二进制递归函数调用自身两次。

下面的函数g()是一个二进制递归的例子,(它是一个Fibonacci binary recursion

int g(int n)

  int i;
  if(n==0)
  
     printf("\n Recursion Stopped");
  
  else
  
     printf("\n Hello");
     g(n-1);
     g(n-2);
  
 

递归关系是g(n) = g(n-1)+g(n-2),对于n&gt;1

求解我们得到 O(2n) 的上限。 函数g()也是Θ(φn), 其中φgolden ratioφ = ((1+ √5)/2)

【讨论】:

以上是关于线性递归、二元递归与运行时的关系的主要内容,如果未能解决你的问题,请参考以下文章

数据-第18课-栈与递归

尾递归和线性递归

数据结构第九篇——栈与递归

浅析C#中的线性递归与尾递归

递归与常见问题

初识webpack