对于家庭作业,我需要了解跳过列表的工作原理。
我已经编程了2年多了(我知道实际上并没有那么长),我什至从未听说过跳过列表。
我查看了所有可以找到的指南,但我仍然几乎不了解它们的工作原理。我什至在“代码审查”中搜索了一个示例实现,但只发现了一个审查。甚至还不是一个完整的实现。我查看了本课程提供的示例实现,这绝对是残酷的。在缺乏适当的方法和单字母变量名称之间,我不知道它是如何工作的。
跳过列表如何工作?要了解更高级的数据结构是否需要了解跳过列表?
对于家庭作业,我需要了解跳过列表的工作原理。
我已经编程了2年多了(我知道实际上并没有那么长),我什至从未听说过跳过列表。
我查看了所有可以找到的指南,但我仍然几乎不了解它们的工作原理。我什至在“代码审查”中搜索了一个示例实现,但只发现了一个审查。甚至还不是一个完整的实现。我查看了本课程提供的示例实现,这绝对是残酷的。在缺乏适当的方法和单字母变量名称之间,我不知道它是如何工作的。
跳过列表如何工作?要了解更高级的数据结构是否需要了解跳过列表?
Answers:
过去,在数据结构课程中,我们学习了AVL树是如何工作的。我本可以在我的一门课上学过,但是讲师说“您永远不会真正使用它”,而是让我们学习2-3棵树和b *树。那些日子里,内存很紧张,进程都是单线程的。当单链接列表也可以工作时,您无需使用双端队列。
跳过列表在今天变得更加普遍,存在更多的可用内存和并发性成为问题(与具有AVL树的所有内容相比,在跳过列表中充当编写器时根本不需要锁定太多)。
坦白说,这是我现在最喜欢的数据结构,因为我可以很容易地推断出它的底层工作方式以及使用它的有利或不利之处。
您将不需要从头开始编写一个代码(除非您将其作为面试问题而获得,但是那样就很可能实现AVL树)。
你是要需要了解你为什么要选择ConcurrentSkipListMap
在Java中,而不是一个HashMap
或TreeMap
或任何其他地图的实现。
要了解其工作原理,您需要了解二叉树的工作原理。等一下,让我修改一下。您需要了解平衡的二叉树如何工作。如果不平衡二叉树,则其查找不会获得任何真正的优势。
可以说我们有这棵树:
然后在其中插入一个“ 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 TreeMap
或HashMap
。
其中大部分是从我的博客文章“跳过列表”中借用的。