关闭

跳表(Skiplist)

标签: 数据结构跳表
91人阅读 评论(0) 收藏 举报
分类:

跳表是一种随机化的数据结构,基于并联的链表,它的查找效率可以红黑树相提并论(对于大多数操作需要O(log n)平均时间)。基本上,跳表是对有序的链表增加上附加的前进链接,增加十一随机化的方式进行的,所以在链表中的查找可以快速的跳过一部分链表,因此得名。所有操作都以对数的随机化时间进行。具体见图例

跳表

定义

从上面的图中我们可以看出,跳表主要由以下的几个部分来组成:

  • 表头(head):负责维护跳跃表的节点指针。
  • 跳跃表节点:保存元素值,以及多个层。
  • 层:保存着指向其他元素的指针。高层的指针越过的元素数量大于底层的指针,为了提高查找效率,程序总是从高层开始查找,然后随着元素值范围的缩小,慢慢层次降低。
  • 表尾:全部由NULL组成,表示跳表已经到了末尾。

正是由于跳表这样的定义,它具有下面的几个特征:

  1. 一个跳表应该有几层组成。
  2. 跳表的最底层(也就是第一层)包含所有的元素。
  3. 每一层都是一个有序的链表。
  4. 如果元素x出现在滴i层,则所有比i小的层都包含x

具体的描述

既然已经大致的介绍的跳表是一个什么鬼,那么下一步我们看一看它到底怎么使得查找效率和红黑树一样的。

从上面我们知道跳表是按照层来建造的,底层就是一个普通的有序链表。每个更高层都充当下面链表的『快速跑道』,这里在第i层中元素按照某个固定的概率p(通常为0.5或者0.25)出现在第i+1层中,平均起来,每个元素都在1/(1-p)个链表中出现,而最高层的元素(通常是在跳表前端的一个特殊的头元素)在O(log1/p(n))个链表中出现。

1
1-----4---6
1---3-4---6-----9
1-2-3-4-5-6-7-8-9-10

要查找一个目标元素,起步于头元素和顶层链表,并沿着每个链表搜索,直到到达小于或者等于目标的最后一个元素,如果等于直接返回,如果小于,则跳到这个节点的下一层链表继续查找。

插入和删除的实现基本和相应的链表的操作类似,除了『高层』元素必须咋多个链表中插入和删除之外。

跳表不像某些传统的平衡树数据结构那样提供绝对的最坏情况性能保障,因为用来建造跳表的扔硬币方法总有可能(尽管概率很小)生成一个非常糟糕的不平衡结构。但是在实际中的大部分情况下,它效率不错;最重要的是随机化的平衡方案比在平衡二叉查找树中用的确定性平衡方案更『容易实现』。

实现步骤

  1. 给定一个有序的链表。
  2. 选中链表中最大和最小的元素,然后从其他元素中按照一定概率随机选出一些元素,将这些元素组成有序的链表。这个新的链表称为一层,原链表称为其下一层。
  3. 为刚选出的每个元素添加一个指针域,这个指针指向下一层中值同自己相等的元素。TOP指针指向该层首元素。
  4. 重复2,3步,知道不能选择出做大最小元素以外的元素。

C与C++实现

参考文献

维基百科
Skip List(跳跃表)原理详解与实现
Redis设计与实现–跳表

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:684次
    • 积分:21
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档