递归与迭代树遍历

艾希温

因此,我正在研究树遍历算法。例如,在遍历Kd树时,我们的目标是将节点向下遍历到叶子。这并不仅仅是树搜索,而仅仅是叶遍历的根。

在这种情况下,递归解决方案就足够了。但是,在像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)。因此,我想知道迭代解决方案是否有任何缺点,或者它确实比纯递归更快。有什么我想念的吗?

吉姆·米歇尔

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章