RRB树维持什么不变量?

时间:2012-12-22 22:38:34

标签: algorithm scala data-structures clojure tree

Relaxed Radix Balanced Trees(RRB-trees)是不可变向量(在Clojure和Scala中使用)的推广,它具有“有效恒定”的索引和更新时间。 RRB树保持有效的索引和更新,但也允许有效的连接(log n)。

作者以我难以理解的方式呈现数据结构。我不太清楚每个节点维护的不变量。

在2.5节中,他们描述了他们的算法。我认为他们确保索引到节点只需要在基数搜索后进行线性搜索的额外步骤。我不明白他们是如何得出他们的额外步骤的公式,我想也许我不确定每个变量的意思(特别是“总共p个子树分支”)。

RRB树连接算法的工作原理是什么?

2 个答案:

答案 0 :(得分:4)

他们确实描述了2.4节中的不变量。但是,如前所述 B树节点不便于基数搜索。相反,我们选择 允许节点大小在m之间的范围的初始不变量 这定义了一系列以平衡树为起点的平衡树 众所周知的2-3棵树,3-4棵树和(m = 32)31-32棵树。这个 不变量确保平衡并实现基数分支搜索 大多数情况。偶尔需要几步线性搜索 在基数搜索之后找到正确的分支。 所需的额外步骤会在更高的级别上增加。“

查看他们的公式,看起来他们已经计算出子树中存储的最大和最小值。两者之间的差异是点下面的最大值和最小值之间的最大可能差异。如果将其除以插槽下方的值数,则在计算出要查看的插槽以查看它是否包含您要搜索的索引时,可以使用最大插槽数。

答案 1 :(得分:2)

@mcdowella是正确的,这是他们对轻松节点的看法。但是,如果您要拆分并加入节点,则从 m m -1的范围意味着您有时需要调整到 m - 1( m -2?)节点,以便从节点添加或删除单个元素。这似乎非常低效。我认为它们意味着在 m 和(2 m ) - 1之间,因为它允许节点在它们变得太大时被分成2个,或者当它们连接成2个节点时太小而不需要更改第三个节点。因此,本文中“2 m ”中缺少“2”这是一个错字。 Jean Niklas L’orange's masters thesis支持我。

此外,所有严格节点都具有相同的长度,必须是2的幂。原因是Rich Hickey的Clojure PersistentVector中的优化。好吧,我认为重要的是将所有严格的节点打包(稍后会详细介绍),这样你就不必猜测树的哪个分支下降了。但是能够进行位移和位掩码而不是除法是一个很好的奖励。我没有在轻松的Scala Vector上计算get()操作,而是relaxed Paguro vector is about 10x slower than the strict one。因此,如果您反复插入0,它会尽一切努力尽可能严格,甚至产生2个严格级别。

它们的树也有一个均匀的高度 - 所有叶节点与根的距离相等。我认为,如果放松的树木必须在一个层次之内,但是不确定会给你带来什么,那么它仍然有效。

宽松的节点可以有严格的子节点,但反之亦然。

必须从左侧(低索引)填充严格的节点,没有间隙。任何非完整的Strict节点必须位于树的右侧(高索引)边缘。如果你确实附加了焦点或尾部,那么所有严格的叶子节点都可以是满的。(更多内容见下文)。

您可以通过在Paguro implementation中搜索debugValidate()方法来查看大多数不变量。这不是他们的论文,但它主要基于它。实际上,论文中也没有提到Scala implementation中的“显示”变量。如果你要研究这些东西,你可能想先看看Clojure PersistentVector,因为RRB树里面有一个。它与RRB树之间的两个差异是1.RRB树允许“放松”节点和2.RRB树可以具有“焦点”而不是“尾部”。焦点和尾部都是小缓冲区(可能与严格的叶节点大小相同),不同之处在于焦点可能会定位到最后插入/附加到的向量的任何区域,而尾部总是在末尾(PerSistentVector只能附加到,从不插入)。这两个差异允许O(log n)任意插入和删除,以及O(log n)split()和join()操作。