平衡二叉树与索引跳过列表

时间:2013-04-01 17:17:58

标签: algorithm data-structures language-agnostic binary-tree skip-lists

不确定问题是在这里还是程序员(或其他一些SE网站),但我对平衡二叉树和indexable skiplists之间的相关差异感到好奇。问题出现在this question的背景下。来自维基百科:

  

跳过列表是一种概率数据结构,似乎可能取代平衡树作为许多应用程序的首选实现方法。跳过列表算法与平衡树具有相同的渐近预期时间范围,更简单,更快速,占用空间更少。

跳过列表的空间要求是否取决于层次结构的深度?并且二叉树不是更容易使用,至少对于搜索(在平衡BST中授予,插入和删除可能是棘手的)?跳过列表还有其他优点/缺点吗?

4 个答案:

答案 0 :(得分:5)

(问题的某些部分(易用性,简单性等)有点主观,我会在本文末尾回答。)

让我们来看看空间使用情况。首先,假设您有一个包含n个节点的二叉搜索树。所需的总空间使用量是多少?好吧,每个节点都存储一些数据和两个指针。您可能还需要一些信息来维护余额信息。这意味着总空间使用量为

  

n *(2 * sizeof(指针)+ sizeof(数据)+ sizeof(余额信息))

因此,让我们考虑一个等效的跳过列表。跳过列表使用的实际内存量取决于节点的高度,这是绝对正确的,但我们可以讨论跳过列表所使用的预期空间量。通常,您从跳过列表中选择一个节点的高度,从1开始,然后重复翻转一个公平的硬币,只要翻转头部就会增加高度,并在翻转尾部时立即停止。鉴于此设置,跳过列表中预期的指针数量是多少?

概率论的一个有趣结果是,如果你有一系列具有概率p的独立事件,那么在事件发生之前你需要大约1 / p次试验(在预期中)。在我们的硬币翻转示例中,我们正在翻转硬币直到它出现尾巴,并且因为硬币是一个公平的硬币(头部概率为50%),所以在我们翻尾之前所需的预期试验次数是2次。由于最后一次翻转结束了增长,节点在跳过列表中增长的预期次数是1.因此,在期望中,我们期望平均节点中只有两个指针 - 一个初始指针和一个添加指针。这意味着预期的总空间使用量为

  

n *(2 * sizeof(指针)+ sizeof(数据))

将其与平衡二叉搜索树中节点的大小进行比较。如果存储余额信息需要非零空间,则跳过列表确实会使用(预期)比平衡BST更少的内存。请注意,许多类型的平衡BST(例如treap s)需要大量余额信息,而其他(red/black treesAVL trees)具有余额信息,但可以隐藏这些信息。它的指针位是有序的,而其他指针(splay trees)根本没有任何余额信息。因此,这不是保证胜利,但在许多情况下它会使用空格。

至于你关于简单,轻松等的其他问题:这真的取决于你。我个人发现在BST中查找元素的代码比在skiplist中进行查找的代码要容易得多。然而,平衡BST中的旋转逻辑通常比跳过列表中的插入/删除逻辑复杂得多;尝试看看你是否可以在没有咨询参考的情况下在红/黑树中发出所有可能的旋转情况,或者看看你是否能够记住一个展开树中的所有zig / zag与zag / zag情况。从这个意义上讲,记住用于从跳过列表中插入或删除的逻辑可能会更容易一些。

希望这有帮助!

答案 1 :(得分:2)

  

并不是二叉树更容易使用,至少对于搜索而言   (在平衡的BST中授予,插入和删除可能很棘手)?

树是“更递归”(树和子树),而SkipLists是“更多迭代”(数组中的级别)。当然,这取决于实现,但SkipLists对于实际应用也非常有用。

在树中搜索更容易,因为您不必迭代数组中的级别。

  

跳过列表还有其他优点/缺点吗?

  • SkipLists“更容易”实施。这是一个小小的相对,但实现一个全功能的SkipList比在BinaryTree中删除和平衡操作更容易。

  • 树可以是持久的(更适合函数式编程)。

  • 从二进制树中删除SkipLists中的项目比删除内部节点更容易。

  • 将项目添加到二叉树更容易(保持余额是另一个问题)

  • 二叉树是确定性的,因此更容易研究和分析它们。

我的提示:如果您有时间,则必须使用平衡二进制树。如果您没有时间,请使用“跳过列表”。如果没有时间,请使用库。

答案 2 :(得分:2)

到目前为止未提及的是跳过列表对于并发操作可能是有利的。如果你读了ConcurrentSkipListMap的源代码,由Doug Lea撰写...深入评论。它提到:

搜索树没有已知的有效无锁插入和删除算法。索引节点的“向下”链接的不变性(与真树中可变的“左”字段相对)使得仅使用CAS操作易于处理。

答案 3 :(得分:1)

你说这不是一个完美的论坛。

您引用的评论是由原始跳过列表文章的作者撰写的:不完全是一个无偏见的断言。已经23年了,红黑树似乎比跳过列表更普遍。例外是redis key-value pair database,其中跳过列表作为其数据结构中的一个选项。

跳过列表非常酷。但是我在一般随机情况下能够显示的唯一空间优势是不需要存储平衡标志:每个值两位。这假设层次结构足够密集以复制二叉树性能。你可以把它当作决定论的代价(副随机化)。 SL的一个很好的特性是你可以使用密度较小的层次结构来交换空间的恒定速度因子。

旁注:如果您不需要按排序顺序遍历,则不会经常讨论,只需加密密钥即可随机化不平衡二进制树(即映射到伪随机密码)带有非常简单的文字,如RC4)。实施这些树绝对是微不足道的。