跳跃表详解

跳跃表[SkipList]是一种基于有序链表的扩展,简称跳表,其就是使用关键节点作为索引的一种数据结构

怎样能更快查找到一个【有序链表】的某一节点呢?

可以利用类似【索引】的思想,提取出【链表】中的【部分关键节点】

比如:给定一个长度是7的有序链表,节点值依次是1->2->3->5->6->7->8 那么我们可以取出所有值为【奇数的节点】作为关键点。

此时如果要插入一个值是4的新节点,不再需要和原节点8,7,6,5,3逐一比较,只需要比较关键节点7,5,3

 

确定了【新节点在关键节点中的位置】(3和5之间),就可以【回到原链表】,迅速定位到对应的位置插入(同样是3和5之间)

 

 

多层关键节点多层索引

当然,既然已经提取出了【一层关键节点】作为【索引】,那么可以进一步提取索引,提出一层索引的索引

 

有了2级索引之后,新的节点可以先和2级索引比较,确定大体范围; 然后再和1级索引比较;最后再回到原链表,找到并插入对应位置

层级极限是什么?

当节点足够多的时候,不止能提出2层索引,还可以向更高层次提取,保证每一层是上一层节点数的【一半】至于提取的【极限】,则是:

同一层只有【两个节点】的时候,因为一个节点没有比较的意义。

这样的【多层链表】结构,就是所谓的【跳跃表】

怎么从新节点当中选取一部分提到上一层(抛硬币法)?

当大量的新节点通过逐层比较,最终插入到原链表之后,上层的索引节点会渐渐变得不够用。

这时候需要从新节点当中选取一部分提到上一层。

使用【抛硬币】 也就是随机决定新节点是否提拔,每次向上提拔一层的几率是50%

为什么要用抛硬币?

①. 因为跳跃表删除和添加的节点是不可预测的,很难用一种有效的算法来保证跳表的索引部分始终均匀。

②. 随机抛硬币的方法虽然不能保证索引绝对均匀分布,却可以让大体趋于均匀

跳跃表【插入节点】的流程?

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

2. 把新节点插入到原链表。O(1)

3. 利用抛硬币的随机方式,决定新节点是否提升为上一级索引。

结果为“正”则提升并继续抛硬币,结果为“负”则停止。O(logN)

删除节点的步骤:

1. 自上而下,查找第一次出现节点的索引,并逐层找到每一层对应的节点。O(logN)

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

跳跃表和二叉查找树的区别?

跳跃表的优点:

维持【结构平衡】的成本比较低,完全依靠【随机】

二叉查找树:

在多次插入、删除后,需要rebalance来重新调整结构平衡

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值