【问题标题】:PreOrder Traversal Iterativ vs Recursive Time ComplexityPreOrder Traversal Iterativ vs Recursive Time Complexity
【发布时间】:2018-08-14 18:12:24
【问题描述】:

我正在为我的 Web 应用程序使用树。例如,创建一个个人资料网站,每个个人资料可以有 0..n 个朋友。另外,我想在最好的时间寻找朋友。为此,我使用了二叉搜索树和广度优先搜索 (BFS)。

我测量了我的两个函数在递归和迭代列表中搜索朋友的时间,令我惊讶的是递归函数更快。我认为迭代函数比迭代更快,我只在迭代函数中使用了一次 while 循环,时间复杂度为 O(n)。有人可以解释这里出了什么问题以及为什么递归函数更快:

时间递归:1.3000000035390258

 preorderRec(root){
    if(root === null) {
      return;
    }
    console.log(root.data);
    if(root.left) {
      this.preorderRec(root.left);
    }
    if(root.right) {
      this.preorderRec(root.right);
    }
    return root;

  }

时间迭代:0.997000001117587

   preOrderIterativ(root) {
if(root === null) {
  return;
}
const stack = [root];
const stack2 = [];
while(stack.length) {
  //const node = stack.pop();
  const node = stack.pop();
  stack2.push(node)
  if(node.left) {
    stack.push(node.left)
  }
  if(node.right) {
    stack.push(node.right)
  }
}

return stack2;

} }

解决方案:问题出在while循环中的console.log。我使用 repl.it 作为编辑器,在我删除 console.log 后,性能得到了提升

【问题讨论】:

  • 这是完整的代码吗?您的 preorderRec 函数遍历树,但不对其进行任何操作。没有像迭代版本中那样的推送、弹出或返回,而且迭代版本看起来不会超过 1 个节点。
  • 你的preOrderIterativ函数逻辑不正确,是不是上面给出的测试结果是同一个程序?
  • java != javascript。来吧,它甚至在两者的工具提示中都这么说!!!
  • 嗨,递归函数只是返回根
  • @NicholasTower preorderRec 代码记录所有节点数据。 preOrderIterativ 有缺陷,只记录树根的数据,因为它从不迭代孩子。

标签: javascript data-structures


【解决方案1】:

在迭代解决方案中,您正在使用另一种数据结构 (array)。除此之外,您还在不断地执行插入push 和删除pop 操作。这些操作中的每一个都是O(n) 时间复杂度。使用递归解决方案,您正在使用call stack,这就是javascript 运行事物的方式。我不知道大 O。

【讨论】:

  • 好吧奇怪。我怎样才能使它成为堆栈?我认为添加和删除操作是 O(1)。我不明白数组和堆栈的不同之处。如果我创建一个函数添加而不是使用推送功能,它有什么不同?
  • 您可以手动创建链接列表并将其用作堆栈。这将为您提供 O(1) 的插入和删除。
猜你喜欢
  • 1970-01-01
  • 2017-04-24
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2015-09-15
  • 1970-01-01
相关资源
最近更新 更多