Skip list是一个用于有序元素序列快速搜索的数据结构,由美国计算机科学家William Pugh发明于1989年。它的效率和红黑树以及 AVL 树不相上下,但实现起来比较容易。作者William Pugh是这样介绍Skip list的:
Skip lists are a probabilistic data structure that seem likely to supplant balanced trees as the implementation method of choice for many applications. Skip list algorithms have the same asymptotic expected time bounds as balanced trees and are simpler, faster and use less space.
Skip list是一个“概率型”的数据结构,可以在很多应用场景中替代平衡树。Skip list算法与平衡树相比,有相似的渐进期望时间边界,但是它更简单,更快,使用更少的空间。
Skip list是一个分层结构多级链表,最下层是原始的链表,每个层级都是下一个层级的“高速跑道”。
这里写图片描述
跳跃的表的性质包括:
某个i层的元素,出现在i+1层的概率p是固定的,例如常取p=1/2或p=1/4;
平均来讲,每个元素出现在1/(1-p)个链表中;
最高的元素,例如head通常采用Int.MIN_VALUE作为的最小值,会出现在每一层链表中;
原始的链表元素如果是n,则链表最多
这里写图片描述
层。例如,p=1/2时,层数为
这里写图片描述
。
跳跃表的空间复杂度为O(n),插入删除的时间复杂度是
这里写图片描述
。例如,p=1/2时,复杂度为
这里写图片描述
。
相关资料
Skip list的维基百科;
《算法导论》网易公开课Skip list。
跳跃表的构建
这里描述一下网易公开课《算法导论》“跳跃表”这一节的内容。
空的跳跃表头尾相连的双向链表。
这里写图片描述
向链表中放入key-value,假如key是1。
这里写图片描述
此时,不断投掷硬币,如果是反面,则不提升该节点,停止投掷硬币;否则不断提升该节点,并且垂直方向进行节点连接。
这里写图片描述
如果上一步没有提升,再插入key-value,key等于2,然后不断投掷硬币,发现是投了一次正面,需要提升一次。但第二次投的是反面,不再提升。
这里写图片描述
再插入key-value,key等于3,然后不断投掷硬币,发现第一次就投了反面,不提升。
这里写图片描述
这样的规则一直持续下去。由于连续投正面的概率是0.5,0.5*0.5……,所以某一个节点提升很多层的概率是很低的。这也是为什么说跳跃表是一种概率型数据结构的来源。
跳跃表的查询也比较简单。例如要查找key是3的节点,则从最上层开始查找,直到找到大于或等于3的位置,然后返回上一个节点