Algorithm 算法的迭代和递归版本是否具有相同的时间复杂度?

Algorithm 算法的迭代和递归版本是否具有相同的时间复杂度?,algorithm,complexity-theory,time-complexity,Algorithm,Complexity Theory,Time Complexity,比如说,斐波那契级数的迭代和递归版本。它们有相同的时间复杂度吗?是的,如果你在算法的基础上使用完全相同的思想,这并不重要。然而,递归在迭代方面通常很容易使用。例如,编写河内塔的递归版本相当容易。将递归版本转换为相应的迭代版本是困难的,而且容易出错,即使可以这样做。事实上,有一个定理表明,每个递归算法都可以转换为等价的迭代算法(这样做需要使用一个或多个堆栈数据结构迭代地模拟递归,以保存传递给递归调用的参数) 若采用某种递归算法,可以将所有函数局部变量存储在一个数组中,从而有效地模拟堆上的堆栈,从而

比如说,斐波那契级数的迭代和递归版本。它们有相同的时间复杂度吗?

是的,如果你在算法的基础上使用完全相同的思想,这并不重要。然而,递归在迭代方面通常很容易使用。例如,编写河内塔的递归版本相当容易。将递归版本转换为相应的迭代版本是困难的,而且容易出错,即使可以这样做。事实上,有一个定理表明,每个递归算法都可以转换为等价的迭代算法(这样做需要使用一个或多个堆栈数据结构迭代地模拟递归,以保存传递给递归调用的参数)

若采用某种递归算法,可以将所有函数局部变量存储在一个数组中,从而有效地模拟堆上的堆栈,从而将其转换为迭代算法。如果这样做,迭代和递归之间没有区别


请注意,有(至少)两种递归斐波那契算法,因此为了准确地说明示例,您需要指定您所谈论的递归算法。

答案在很大程度上取决于您的实现。对于您给出的示例,有几种可能的解决方案,我想说,实现解决方案的简单方法在迭代实现时具有更好的复杂性。以下是两种实现:

int iterative_fib(int n) {
   if (n <= 2) {
     return 1;
   }
   int a = 1, b = 1, c;
   for (int i = 0; i < n - 2; ++i) {
     c = a + b;
     b = a;
     a = c;
   }
   return a;
}
int recursive_fib(int n) {
  if (n <= 2) {
    return 1;
  }
  return recursive_fib(n - 1) + recursive_fib(n-2);
}
这里,递归算法的复杂性与迭代解一样是线性的。我上面介绍的解决方案是用自上而下的方法来动态规划解决您的问题。自下而上的方法将产生与我介绍的迭代解决方案非常相似的结果。 有很多关于动态规划的文章,包括

根据我在经验中遇到的问题,一些问题很难用自下而上的方法解决(即迭代解决),而另一些问题则很难用自上而下的方法解决。 然而,该理论指出,每个有迭代解的问题都有一个具有相同计算复杂性的递归解(反之亦然)


希望这个答案有帮助。

是的,每个迭代算法都可以转换为递归版本,反之亦然。一种是通过传递continuations,另一种是通过实现堆栈结构。这样做不会增加时间复杂度


如果您可以优化尾部递归,那么每个迭代算法都可以转换为递归算法,而不会增加渐近内存复杂性。

计算fibanocci级数的特定递归算法效率较低。 通过递归算法

考虑FIB(4)的发现情况
                int fib(n) :
                        if( n==0 || n==1 )
                            return n;
                        else
                            return fib(n-1) + fib(n-2)
现在,当n=4执行上述算法时

                            fib(4)

                    fib(3)             fib(2)

                fib(2)   fib(1)     fib(1)   fib(0)

             fib(1)  fib(0) 
它是一棵树。它说,为了计算fib(4),你需要计算fib(3)和fib(2)等等

请注意,即使对于较小的值4,fib(2)计算两次,fib(1)计算三次。对于大量的数据,此添加的数量会增加

有一种推测,计算fib(n)所需的加法数为

因此,这种重复是导致该特定算法性能降低的原因之一

斐波那契级数的迭代算法速度要快得多,因为它不涉及计算冗余的东西


但是,所有算法的情况可能都不一样。

计算斐波那契序列的迭代算法和递归算法各有不同的复杂度。我认为你可以合理地说,如果它们的复杂度不同,那么它们就不是“同一算法”的迭代和递归版本。它们是不同的算法,当然,计算相同结果的不同算法不一定具有相同的复杂性。也就是说,以相同的名称引用相关算法组是很常见的。例如,根据您选择轴心的方式和处理分区两侧的顺序,快速排序的行为会有所不同,但所有的可能性通常都称为“快速排序”。。。。由此可知,两位代码是否可以被描述为“相同的算法”,在某些情况下取决于您的语言/编译器是否实现尾部递归。如果递归版本创建了一个它不需要的调用堆栈,那么它是一个空间复杂度较低的不同算法。@SteveJessop:还有一个可能的崩溃错误:)
我想说,实现解决方案的简单方法在迭代实现时具有更好的复杂度。
我想说迭代版本不再简单。斐波那契数列的问题是,编写指数递归版本非常容易,但编写指数迭代版本非常困难,因此编写迭代算法时出现的第一个版本并不是很幼稚,你必须花点心思来编写任何迭代。
                            fib(4)

                    fib(3)             fib(2)

                fib(2)   fib(1)     fib(1)   fib(0)

             fib(1)  fib(0) 
                     fib(n+1) -1