如何重新平衡随机二叉搜索树

时间:2017-09-19 01:52:53

标签: data-structures tree binary-search-tree avl-tree

情况如下:有一个平衡的二进制搜索树,可以通过数十个线程访问。因此,当我需要插入或删除节点时,由于并发性,我不想锁定整个树。随着时间的推移,它变得不再平衡。当树没有那么忙时,我终于有机会锁定并重新平衡它。我怎么能这样做?

或者我可以使用更好的数据结构吗?

1 个答案:

答案 0 :(得分:1)

您实际上可以使用Day-Stout-Warren algorithm重新平衡它。它在节点数量上是线性的,因此可能需要一段时间。此外,这种方法提出了一个问题:如果在您不重新平衡被读取的树的时间间隔内,它很快会变得非常不平衡,并且所有后续读取都在例如O(N)中完成而不是O(logN)?为了不锁定东西,可以将这种性能损失持续数小时吗?你确定会有表演胜利吗?

如果你可以忍受缺乏线性化(即你写了一个值,但是当你找不到它之后立即搜索它;它最终会在那里,但是100ms-10s可能会通过),你可以实现一个"复制写"树:所有写入都由一个线程完成(具有重新平衡),并且您定期将树克隆为只读副本,可以通过读取线程而无需任何并发控制来使用,您只需要以原子方式发布它。如果树是在一个连续的内存块上实现的,可以特别快速地完成,该内存块可以作为一个整体进行复制并作为一个整体进行释放/垃圾收集。

另一种选择是使用并发skip list:它提供对数平均案例搜索/删除/插入时间,并且更容易并行化。如果您碰巧使用它,则有一个标准的无锁implementation for Java。您可以找到有关并发跳过列表和平衡搜索树here的更多信息。特别是,您可以找到chromatic tree的提及,这是一个针对并发重新平衡进行了优化的二叉搜索树。