Javascript 迭代与递归的最大区别是什么?

Javascript 迭代与递归的最大区别是什么?,javascript,big-o,Javascript,Big O,迭代与递归的最大区别是什么?为什么运行时间如此不同。我假设O(n),因为它有一个迭代循环 这是一个带有精美图表的媒体 function factorial (n) { if( n === 0 || n === 1 ) { return 1; } let prev = 1; let ret; while(n >= 2) { ret = prev * n; prev = ret; n--; } return ret; } funct

迭代与递归的最大区别是什么?为什么运行时间如此不同。我假设O(n),因为它有一个迭代循环

这是一个带有精美图表的媒体

function factorial (n) {
  if( n === 0 || n === 1 ) {
    return 1;
  }
  let prev = 1;
  let ret;
  while(n >= 2) {
    ret = prev * n;
    prev = ret;
    n--;
  }
  return ret;
}

function factorialR (n) {
  if( n === 0 || n === 1 ) {
    return 1;
  } else {
    return n * factorialR(n - 1);
  }
}

递归版本似乎需要更长的时间。请参阅。

是,这些函数都具有
O(n)
计算复杂性,其中n是传递给初始函数调用的数字

第一个函数执行
while
循环中的(
O(1)
complexity)语句,以获得
O(n)
的总体复杂度

第二个函数递归调用自己
n
次,没有任何循环,因为(再次)总体复杂度为
O(n)

如果您想降低函数多次调用的计算复杂度,我会创建一个查找表来保存从以前的调用中计算出的值,从而在
O(n)
中运行函数的
m
调用(其中
n
是有史以来传递的最大数),而不是以
O(n*m)
(或
O(n^2)
)时间运行的
m
调用

如果

递归版本似乎需要更长的时间


这不是由于计算复杂性,而是由于编译器如何使用不同的方法。函数调用通常比简单的
while
循环有更多的开销(不过,这种优化在现实生活中几乎不需要担心-代码可读性和可维护性在大多数情况下更重要)。

谢谢,我已经有点明白了。问题更多的是。。。。为什么同一个
n
的时间如此不同。。。5毫秒与150毫秒相比,如何在Big O中捕捉到这一点?如果你指的是Gabriele Petrioli的答案,那么这一部分是相当误导的-他使用的是
日期。现在
(这不是非常精确),并且只运行相对较少的迭代次数(与实际性能测试相比)。它看起来也不准确,我这里得到的是3-5毫秒,而不是10-15毫秒:在最新版本的Chrome中。但是5ms vs 150ms是可能的,即使计算复杂度相同(考虑到函数调用的开销)。JavaScript有尾部调用优化吗?@laptou应该有,但很少有环境实现了它,不幸的是,你可以说它是O(n)对于这两种情况,除了递归调用的常量要大得多之外?