跳表skiplist

跳表介绍

跳跃列表(也称跳表)是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作须要O(logn)平均时间)。

跳表是对有序的链表添加上附加的前进链接,添加是以随机化的方式进行的,所以在列表中的查找能够高速的跳过部分列表元素,因此得名。跳表的全部操作都以对数随机化的时间进行。

一个简单的跳表如下所示:
在这里插入图片描述

传统意义的单链表是一个线性结构,向有序的链表中插入一个节点须要O(n)的时间,查找操作须要O(n)的时间。假设我们使用上图中的跳表,由于我们能够先通过每一个节点的最上层的指针先进行查找,这样子就能跳过大部分的节点。然后再缩减范围,对以下一层的指针进行查找,若仍未找到,缩小范围继续查找。这样能够大大降低降低查找所需时间。

上面基本上就是跳表的思想。每个结点不单单仅仅包括指向下一个结点的指针。可能包括非常多个指向其余结点的指针,这样就能够跳过一些不必要的结点,从而加快查找、删除等操作。对于一个链表内每一个结点包括多少个指向其余节点的指针,是通过一个随机函数生成器得到的。

查找操作

我们以查找19为例。图解查找过程。
在这里插入图片描述

  1. 先从最上层的跳跃区间大的层开始查找。从头结点开始,首先和23进行比较,小于23(此时查找指针在图中“1”位置处)。查找指针到下一层继续查找。
  2. 然后和9进行比较,大于9,查找指针再往前走一步和23比较,小于23(此时查找指针在图中“2”位置处)。因此这个值肯定在9结点和23结点之间,查找指针到下一层继续查找。
  3. 然后和13进行比较,大于13,查找指针再往前走一步和23比较,小于23(此时查找指针在图中“3”位置处)。因此这个值肯定在13结点和23结点之间,查找指针到下一层继续查找。
  4. 此时,我们和19进行比较,找到了。

插入操作

插入和删除的实现很像对应的链表操作,除了"高层"元素必须在多个链表中插入或删除之外。插入包括例如以下几个操作:

  1. 查找到须要插入的位置。
  2. 申请新的结点。
  3. 调整指针。

在找到插入的位置之后,新节点按照一定的概率出现在每层上,因此需要保存连接到插入位置的全部层的后继指针。

我们用一个暂时数组保存全部层的插入点处的后继指针。在寻找插入点的时候就能够完毕赋值。
在这里插入图片描述

删除操作

删除操作类似于插入操作,包括例如以下3步:

  1. 查找到须要删除的结点。
  2. 删除结点。
  3. 调整指针。

删除操作也需要一个暂时数组保存每层的指针域,原理和插入类似。不再赘述。

释放表的操作比較简单,仅仅要像单链表一样释放表就可以。

概率均衡技术

跳表使用概率均衡技术而不是使用强制性均衡,因此,对于插入和删除结点比传统上的平衡树算法更为简洁高效。

跳跃列表是按层建造的。底层是一个普通的有序链表。每一个更高层都充当以下列表的“高速跑道”,这里在层 i 中的元素按某个固定的概率 p (通常为0.5或0.25)出如今层 i+1 中。平均起来。每一个元素都在 1/(1-p) 个列表中出现,而最高层的元素(一般是在跳跃列表前端的一个特殊的头元素)在 O(log1/p n) 个列表中出现。要查找一个目标元素。起步于头元素和顶层列表,并沿着每一个链表搜索。直到到达小于或着等于目标的最后一个元素。

在每一个链表中预期的查找步数显而易见是 1/p。所以查找的整体代价是 O((log1/p n) / p),当p 是常数时是 O(log n)。通过选择不同 p 值。就能够在查找代价和存储代价之间作出权衡。

跳表不像某些传统平衡树数据结构那样提供绝对的最坏情况性能保证,由于用来建造跳跃列表的扔硬币方法总有可能(虽然概率非常小)生成一个糟糕的不平衡结构。可是在实际中它工作的非常好。随机化平衡方案比在平衡二叉查找树中用的确定性平衡方案easy实现。跳跃列表在并行计算中也非常实用,这里的插入能够在跳跃列表不同的部分并行的进行,而不用全局的数据结构又一次平衡。

跳表性能

空间复杂度:O(n)

查找、插入和删除操作的时间复杂度都为: O(logn)

随机跳表的性能非常不错,节省了大量复杂的调节平衡树的代码。其效率与红黑树、伸展树等这些平衡树能够说相差不大。

跳表还在并发环境下有优势。在并发环境下,假设要更新数据,跳跃表须要更新的部分就比较少,锁的东西也就比较少。所以不同线程争锁的代价就相对少了,而红黑树有个平衡的过程,牵涉到大量的节点,争锁的代价也就相对较高了,性能也就不如前者了。

跳表应用

了解过Redis的都知道,Redis有一个非常实用的数据结构:ZSet,基于它,我们能够非常轻松的实现一个Top N的应用。这个ZSet底层就是利用跳表实现的。

跳表也被用在leveldb中。在一些词典结构中中也经经常使用跳表来实现字典,加快查找速度。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值