带有父指针的二叉搜索树的优点是什么

What are the advantages of binary search trees with parent pointers?

本文关键字:搜索树 是什么 指针      更新时间:2023-10-16
到目前为止

,我一直在用左右指针实现二叉搜索树,比如:

template<typename T>
struct BSTNode{
    BSTNode* left;
    BSTNode* right;
    T data;
}

我遇到了节点也有指向父节点的指针的实现。你为什么要这样做?权衡取舍是什么?

从一个角度来看,你的问题是有效的,因为parent指针在结构中引入了冗余,这在几种情况下是可以避免的。但是在二叉树的情况下,这给了你一个巨大的好处,你可以"向上"跳一个级别(即从一个节点跳到它的父节点),而不记得父节点的地址。如果节点的父节点已知,则可以非常有效和简单地实现几种算法(例如,将节点数与两个值之间的节点数)实现。

权衡是冗余:如果您修改树的结构(例如通过平衡树),您必须记住更新left/rightparent指针以保持树的一致性。

二叉搜索树是指相当通用的二叉树类。对于二叉搜索树,没有理由使用父指针。

但是,二叉树有更专业的变体,其中父指针是有益的。例如,寻找AVL树或红黑色树。这些专业化对树的布局施加了进一步的限制,以实现各种目标,例如通过确保树始终平衡来保证在红黑树中查找/插入/删除O(log n)复杂性。

为了满足这些限制,父指针有时会派上用场。当然,它是通过用内存(指针)换取速度(通过算法查找父级)来实现的。

考虑你最喜欢的关于数据结构的书,看看如何以及为什么,或者维基百科。

它为您提供了更简单、更小的迭代器,这些迭代器不会因树突变而失效。如果没有父节点,遍历例程需要一个大小等于树深度的堆栈,以记住它的位置。如果添加或删除节点,此堆栈将变得过时,迭代器不再正常工作,例如,它可能记得重新访问已删除的祖先节点。

当然,保留父指针的代价是内存中的一棵更大的树。我不能对性能做出任何声明,因为更新父指针需要时间,但也消除了在某些算法中记住父指针的步骤。因此,权衡归结为一方面有一个较小的树,带有大的脆弱迭代器,另一方面有一个较大的树,带有小的健壮迭代器。

这是一种空间速度交易,在概念上不必进行,即它是一个实现细节。您始终可以编写一个函数,该函数返回BST中任何给定节点的父节点,但是调用此类函数需要时间,仅查找值通常更快。

如果您不愿意进行交易,请考虑使用我实现的XOR BST,这是一种妥协。