【问题标题】:What are the advantages of binary search trees with parent pointers?带有父指针的二叉搜索树有什么优点?
【发布时间】:2016-12-31 17:18:10
【问题描述】:

到目前为止,我一直在使用左右指针实现二叉搜索树,例如:

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

我遇到了节点也有指向父节点的指针的实现。你为什么想这么做?有哪些取舍?

【问题讨论】:

标签: c++ binary-search-tree


【解决方案1】:

从某个角度来看,您的问题是有效的,因为 parent 指针在结构中引入了冗余,这在几种情况下是可以避免的。但是在二叉树的情况下,这会给您带来巨大的好处,您可以“向上”跳一级(即从一个节点到其父节点),而无需记住父节点的地址。如果节点的父节点已知,则可以非常有效且简单地实现几种算法(例如,获取两个值之间的节点数)。

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

【讨论】:

    【解决方案2】:

    二叉搜索树指的是相当普遍的二叉树。 对于 二叉搜索树,没有理由有父指针。

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

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

    查看您最喜欢的有关数据结构的书籍以了解其原理和原因,或者查阅维基百科。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多