繁体   English   中英

完美平衡二叉搜索树

[英]Perfect Balanced Binary Search Tree

我有一个关于Balanced BST的理论问题。

我想从常规的unbalanced BST构建具有2^k - 1节点的Perfect Balanced Tree 我能想到的最简单的解决方案是使用排序的Array/Linked list然后将数组递归地划分为子数组,并从中构建Perfect Balanced BST

但是,在Tree很大的情况下,我将需要创建相同大小的Array/List ,这样此方法将消耗大量内存。

另一个选择是使用AVL旋转功能,逐个元素插入,并根据树平衡因子-左右子树的三个高度,通过旋转来平衡树。

我的问题是,我对我的假设正确吗? 是否有任何其他的方法来创建一个完美的BST从不平衡BST

AVL和类似的树并不是完美平衡的,因此我不确定它们在这种情况下如何有用。

你可以建立一个双向链表了树的节点,利用leftright指针代替forwardbackward指针。 对列表进行排序,然后从下至上递归构建树,从左到右使用该列表。

构建大小为1的树是微不足道的:只需将最左边的节点从列表中咬掉即可。

现在,如果您可以构建大小为N的树,则还可以构建大小为2N+1的树:构建大小为N的树,然后咬住单个节点,然后再构建大小为N树。 singe节点将是较大树的根,而两个较小树将是其左和右子树。 由于列表已排序,因此该树自动成为有效的搜索树。

对于2^k-1以外的其他大小,也很容易修改。

更新:由于您是从搜索树开始的,因此您可以直接在O(N)时间和O(log N)空间(甚至在O(1)空间中稍微有点机敏)直接从中建立排序列表,然后进行构建树在O(N)时间和O(log N) (或O(1) )空间中也自下而上。

我还没有找到一个需要完美平衡的搜索树的很好的情况。 如果您的情况确实需要,我想听听。 通常,拥有几乎平衡的树会更好,更快。

如果搜索树很大,则丢弃所有现有结构通常不是一个好主意。 使用旋转功能是在保持大多数现有结构的同时获得更平衡树的好方法。 但是通常您使用合适的数据结构来确保您永远不会有完全不平衡的树。 所谓的自平衡树。

例如,有一个AVL树,一个红黑树或一个八叉树,它们使用稍有不同的旋转方式来使树保持平衡。

如果您确实有一个完全不平衡的树,那么您可能会遇到其他问题。 -就您而言,以AVL方式旋转它可能是修复它的最佳方法。

如果您受内存限制,则可以使用拆分和合并操作,这些操作可以在O(log n)的时间内在AVL树上完成,并且我相信空间是不变的。

如果您还能够维护订单统计信息,则可以对中位数进行分割,使LHS和RHS完美,然后加入。

伪代码(对于递归版本)将为

void MakePerfect (AVLTree tree) {

    Tree left, right;
    Data median;

    SplitOnMedian(tree, &left, &median, &right);
    left = MakePerfect(left);
    right = MakePerfect(right);
    return Join(left, median, right);
}

我相信这可以在O(n)时间和O(log n)空间中实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM