我们都知道有很多自平衡二分查找树(BST),其中最着名的是红黑和AVL。看看AA树和替罪羊树也许有用。
我希望删除插入和搜索,就像任何其他BST一样。但是,删除给定范围内的所有值或删除整个子树是很常见的。所以:
是否有AVL或RB的变体可以帮我解决这个问题?替罪羊树看起来更像这样,但也需要一些改变,任何有经验的人都可以分享一些东西吗?
更准确地说,哪种平衡程序和/或删除程序可以帮助我保持这项行动的时间效率?
答案 0 :(得分:5)
可以在O(logn +对象num)中删除BST值的范围。
我知道最简单的方法是使用Deterministic Skip List数据结构(在继续之前,您可能想要阅读一些关于此数据结构的内容)。 在确定性跳过列表中,所有实际值都存储在底层,并且在它们的上层有指针。插入,搜索和删除都在O(logn)中完成。
范围删除操作可以根据以下算法完成:
范围删除的总复杂度为O(logn +范围内的对象数)。 请注意,如果您选择使用随机跳过列表,则会获得相同的复杂性,但平均而言,并非最坏情况。优点是你不必修复上层指针来满足2-3的需求。
确定性跳过列表具有到2-3树的1-1映射,因此通过更多工作,上述过程也适用于2-3树。
答案 1 :(得分:3)
很久以前在STL之前的日子里,我编写了自己的B-Tree(BST)算法,因为当时我有一个相当大的数据集(2棵树中大约700K项是相互依赖的)。我发现每100-200次插入/删除后重新平衡是我在486和SGI硬件上进行实验时获得的最高性能。此数字现在可能不同,或者可能不同,因为除非您转换为并行模型,否则它似乎确实是算法优化限制。
简而言之,您可以为重新平衡应用修改触发器,并在完成所有修改后允许强制重新平衡。
改善非常显着。 25米后初始直接负荷未完成(杀死过程)。我们去的时候重新平衡也在15米后被杀。限制修改加载每100个mod加载重新平衡,并在不到3米的时间内运行。请注意,在“运行”部分期间,每个初始条目对树进行了0-8次修改。你真的需要考虑在短期内再次修改树时是否总是需要保持平衡。
答案 2 :(得分:2)
至2.如果你有一个100级的B树,你可以通过一个函数调用删除多达100个项目。
To 3.此功能几乎可以应用于任何树,只需实现RemoveSome()函数即可删除N个项并进行重新平衡。对于B树来说,它有点棘手,但可以做到。
注意:我认为你是一名程序员。如果您需要一个完整的,经过测试的现成解决方案,则需要另一个答案。
答案 3 :(得分:2)
如果每个节点存储其高度而不是平衡因子,则应该很容易实现在AVL树中删除节点及其子节点。删除节点后,保持旋转直到两个子节点相差不超过一个。然后向上移动树并重复。与正常删除的唯一真正区别是while
而不是if
来测试高度。
答案 4 :(得分:1)
OCaml标准库中的Set
实现是一个纯功能的AVL树,可以满足您的所有要求,特别是具有集合理论操作(并集,交集,差异)的非常有效的实现。插入和删除是O(log n)。您可以通过将子集表示为集合并使用集合差异来删除子树和元素集。您可以通过创建2元素集并应用set union来同时插入两个元素。