跳过列表如何工作?


14

对于家庭作业,我需要了解跳过列表的工作原理。

我已经编程了2年多了(我知道实际上并没有那么长),我什至从未听说过跳过列表。

我查看了所有可以找到的指南,但我仍然几乎不了解它们的工作原理。我什至在“代码审查”中搜索了一个示例实现,但只发现了一个审查。甚至还不是一个完整的实现。我查看了本课程提供的示例实现,这绝对是残酷的。在缺乏适当的方法和单字母变量名称之间,我不知道它是如何工作的。

跳过列表如何工作?要了解更高级的数据结构是否需要了解跳过列表?



1
教育建议显然是题外话。考虑到这是关于数据结构而不是教育的,我编辑了您的问题以删除这些部分。我还建议阅读我编辑过的Wikipedia链接,并使用有关您仍然不了解的内容的更具体的信息来更新您的问题。

@雪人谢谢。我只是为了防止诸如“问老师”之类的评论而添加。下次我会记住这一点。并且您添加了更改该问题的编辑。最后,我没有要求人们解释他们的工作方式,因为我认为这是题外话(尽管我不会反对一个很好的解释)。我只想知道他们学习的重要性。
Carcigenicate

1
@Carcigenicate解释他们的工作实际上是如何上比的话题,询问是否会在现实世界中看到它们。我们只能猜测您将要做什么以及各个领域。询问我们在现实世界中是否看到它们正在轮询我们是否“是,我看到并使用了它们”或“不,从未听说过”-不会为其他人提供很好或有用的答案。

Answers:


29

过去,在数据结构课程中,我们学习了AVL树是如何工作的。我本可以在我的一门课上学过,但是讲师说“您永远不会真正使用它”,而是让我们学习2-3棵树和b *树。那些日子里,内存很紧张,进程都是单线程的。当单链接列表也可以工作时,您无需使用双端队列。

跳过列表在今天变得更加普遍,存在更多的可用内存和并发性成为问题(与具有AVL树的所有内容相比,在跳过列表中充当编写器时根本不需要锁定太多)。

坦白说,这是我现在最喜欢的数据结构,因为我可以很容易地推断出它的底层工作方式以及使用它的有利或不利之处。

您将不需要从头开始编写一个代码(除非您将其作为面试问题而获得,但是那样就很可能实现AVL树)。

要需要了解你为什么要选择ConcurrentSkipListMap在Java中,而不是一个HashMapTreeMap或任何其他地图的实现。


要了解其工作原理,您需要了解二叉树的工作原理。等一下,让我修改一下。您需要了解平衡的二叉树如何工作。如果不平衡二叉树,则其查找不会获得任何真正的优势。

可以说我们有这棵树:

二叉树

然后在其中插入一个“ 8”。现在我们有了:

不平衡的二叉树

那是不平衡的。所以,我们去做通过一些实现来平衡它的魔力...

平衡树

您又有了一棵平衡的树。但是,我挥了挥手是很多魔术。

让我们跳过一个列表。

理想的跳过清单

这恰好是一种理想的选择。很少,但它显示了跳过列表理想值近似的平衡二叉树性质。

现在,我们要在其中插入一个6。这就像插入链表一样。但是,我们从顶部开始,然后向下。最高点指向5。是6> 5吗?是。好的,现在顶端指向末尾,所以我们往下走(我们在第5位)。下一个是7。6> 7吗?不。因此,我们进入一个级别,并处于基本级别,因此在5的右侧插入6。

我们掷硬币-我们制造的头,我们留下的头。尾巴 无需做任何其他事情。

插入后跳过列表

现在插入8。8> 5?是的 8> 7?是的 现在,我们跟随箭头和周围的堆栈之后又回到了最底层,我们测试8> 11?不。所以我们在7的右边插入8。

我们掷硬币-我们制造的头,我们留下的头。尾巴 无需做任何其他事情。

在另一个插入之后跳过列表

在平衡的树中,我们将对树目前尚未平衡的所有问题进行处理。但这不是一棵树-它是一个跳过列表。我们近似一棵平衡树。

现在插入10。我将避免所有比较。

我们掷硬币-我们制造的头,我们留下的头。头!并再次翻转,再次朝向!再次翻转,确定,有一条尾巴。基本链接列表上方两级。

在又一次插入之后跳过列表

这样做的好处是,现在如果要插入12,我们可以从5 跳到 10,而无需进行所有其他比较。我们可以使用跳过列表跳过它们。而且,我们不必担心平衡树-堆叠的概率性为我们做到了。

为什么这么有用?因为当插入10时,我可以通过将写入锁定在5、7和8指针而不是整个结构上来实现。而且当我这样做时,读者仍然可以在不出现不一致状态的情况下浏览跳过列表。对于并发使用,它更快而不必锁定。为了遍历底层,它的速度比树快(用于树导航的BFS和DFS算法的乐趣-您不必担心它们)。

你会遇到吗?您可能会在某些地方看到它的使用。然后,您将知道为什么作者选择实现而不是为结构选择a TreeMapHashMap

其中大部分是从我的博客文章“跳过列表”中借用的。


谢谢。我什至都不了解一般的实现;我和BST很像。我试图思考如何实现它,而管理所有指针/引用的想法不断使我感到困惑。也许我让自己感到沮丧。谢谢。明天我将以您的回答为起点尝试进行整理。
Carcigenicate,2015年

2
@Carcigenicate您可能还会发现介绍它们的原始文章很有用- 跳过列表:平衡树的概率替代方法。与大多数学术论文相比,这是一个相当容易理解的论文。表2是为什么您会看到它们的使用原因。插入或删除的时间因素增加了其他解决方案的复杂性。

2
链表是“只是一棵退化的非常不平衡的树”。跳过列表是将部分树结构部分添加回列表顶部的一种。就我个人而言,我是持久数据结构的忠实拥护者,在这种特定情况下,树似乎更容易推理。我不认为Clojure,Scala等人是巧合。似乎正在融合某种Bagwell风格的Hash尝试作为其基本数据结构。(Phil Bagwell甚至参与了Scala 2.8的Scala集合框架的重新设计。)但是,跳过列表仍然不错。
约尔格W¯¯米塔格

这是我所读过的跳过列表工作原理的最好解释。
2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.