【问题标题】:Recursive vs Iterative Tree Traversal递归与迭代树遍历
【发布时间】:2019-12-01 00:56:12
【问题描述】:

所以我在研究树遍历算法。例如,在 K-d 树遍历中,我们的目标是将节点向下遍历到叶子。这与其说是树搜索,不如说是从根到叶的遍历。

在这种情况下,递归解决方案就足够了。然而,在像 C 这样的语言中,递归调用函数需要将值压入堆栈并在堆栈帧之间跳转等。标准的递归方法是这样的:

void traverse(Node* ptr){
    if(ptr.left == null && ptr.right == null) return;
    if(ptr.val >= threshold) traverse(ptr.right);
    else if(ptr.val < threshold) traverse(ptr.left);
}
traverse(root);

因此,考虑到二叉树有一个明确的上限(我相信这也可以扩展到其他树类型),以迭代方式执行此遍历是否更有效:

Node* ptr = root;
for(int i = 0; i < tree.maxHeight; i++) {
    if (ptr.left == null && ptr.right == null) break;
    if (ptr.val >= threshold) ptr = ptr.right;
    else if (ptr.val < threshold) ptr = ptr.left
}

二叉树的最大高度是它的节点数,而平衡树的最大高度是 log(n)。因此,我想知道迭代解决方案是否有任何缺点,或者它是否确实比普通递归更快。有什么我遗漏的概念吗?

【问题讨论】:

    标签: algorithm recursion binary-tree tree-traversal


    【解决方案1】:

    您的代码与其说是树遍历,不如说是树搜索。如果您只想从根到叶,那么迭代解决方案更简单、更快,并且将使用更少的内存,因为您不必处理堆栈帧。

    如果您想要对树进行完全遍历:即访问每个节点的顺序遍历,那么您要么编写递归算法,要么实现自己的堆栈,显式推送和弹出节点。您实现自己的堆栈的迭代方法可能会更快,但您无法避免 O(log n)(在平衡二叉树中)或可能的 O(n)(在退化树中)内存使用。实现显式堆栈将使用更少的内存,因为它只需要包含树节点指针,而完整的堆栈帧包含更多。

    【讨论】:

      猜你喜欢
      • 2016-12-15
      • 2011-11-24
      • 2018-07-12
      • 2014-03-11
      • 1970-01-01
      • 2014-08-21
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多