数据结构之跳跃表

打算把【数据结构】整理成一系列博客,今天写的是【跳跃表】(skiplist) 

 

定义:

跳跃链表是一种数据结构,允许快速查询一个有序连续元素的数据链表。快速查询是通过维护一个多层次的链表,且每一层链表中的元素是前一层链表元素的子集。效率和平衡树媲美 —— 查找、删除、添加等操作都可以在O(log n)期望时间下完成, 并且比起平衡树来说, 跳跃表的实现要简单直观得多。基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表,因此得名。(部分引自维基百科)

 

查找

注意看下面的图片(图片来源于网络)

举个例子,如果你想找 14,那么先从 Level 3 开始查找,因为是有序的,所以可以确定是在 Level 3 的 【1,,21】之间,然后再去 Level 2 找,可以确定在【7,21】之间,最后可以在 Level 1 找到

 

插入:

(1)新节点和各层索引节点逐一比较,确定原链表的插入位置。(时间是 O(logN))

(2)把索引插入到原链表。(时间是 O(1))

(3)利用抛硬币的随机方式,决定新节点是否提升为上一级索引。结果为 “正” 则提升并继续抛硬币,结果为 “负” 则停止。(时间是 O(logN))

总体上,跳跃表插入操作的时间复杂度是O(logN),而其所占空间是2N,即空间复杂度是O(N)

 

有一个问题是需要我们注意的,其实也就是上述的(3),可能一开始不是很懂,不急,现在就来说说。

当有很多的新节点通过逐层比较,最终插入到原链表之后,上层的索引节点会逐渐变得不够用,其实就是数量不够多。这时候就需要从新节点当中选取一部分提到上一层,可问题是应该提拔谁?忽略谁呢?

跳跃表的设计者采用了一种有趣的办法:【抛硬币】,也就是随机决定新节点是否可以提拔到上一层,概率是 50%。

如果抛硬币的结果是 “正”,因此把所插入的节点提拔到上一层节点,如果结果是 “负”,则放弃进一步提拔。

这应该可以解答上述的(3)了吧。

 

删除:

(1)自上而下,与链表的节点进行比较,查找第一次出现节点的索引,并逐层找到每一层对应的节点。(时间是 O(logN))

(2)删除每一层查找到的节点,如果该层只剩下一个节点,删除整个一层(原链表除外)(时间是 O(logN))

总体上,跳跃表删除操作的时间复杂度是 O(logN)

 

参考链接:

(1)http://blog.csdn.net/ict2014/article/details/17394259

(2)http://xiaorui.cc/2015/03/27/redis%E7%9A%84sorted-set%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84skip-list%E8%B7%B3%E8%B7%83%E8%A1%A8/

(3)http://mp.weixin.qq.com/s/COBdoHWDhlw4rmG_fGFhSA(一个通俗易懂讲解算法的微信公众号)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值