跳表(Skiplist)

原创 2016年05月30日 16:18:18

跳表是一种随机化的数据结构,基于并联的链表,它的查找效率可以红黑树相提并论(对于大多数操作需要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设计与实现–跳表

版权声明:本文为博主原创文章,未经博主允许不得转载。

HashMap/跳表(SkipList)/红黑树比较及ConcurrentSkipListMap源码解析

csdn.net/sunxianghuang/article/details/52221913 转载地址:http://blog.csdn.net/sunxianghuang/article/det...
  • Wj741238436
  • Wj741238436
  • 2017年06月22日 11:03
  • 819

SkipList跳表C++实现

跳跃列表(也称跳表)是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间)。...
  • u012819953
  • u012819953
  • 2014年05月24日 11:15
  • 820

JAVA SkipList 跳表 的原理和使用例子

为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等。 想象一下,给你一张草稿纸,一只笔,一个编辑器,你能立即实现一颗红黑树,或者AVL树 出来吗...
  • bigtree_3721
  • bigtree_3721
  • 2016年05月01日 21:58
  • 5853

跳跃表(Skip List)的实现及测试 C++实现

//skipnode.h头文件:#include using namespace std; struct skipnode//表示一个结点的结构体 { int data;//元素的值 int le...
  • green_whale06
  • green_whale06
  • 2015年07月06日 09:42
  • 655

跳表(SkipList)与其在java中的使用

跳表(SkipList)这种数据结构算是以前比较少听说过,它所实现的功能与红黑树,AVL树都差不太多,说白了就是一种基于排序的索引结构,它的统计效率与红黑树差不多,但是它的原理,实现难度以及编程难度要...
  • fjs_cloud
  • fjs_cloud
  • 2014年02月05日 20:38
  • 4698

浅析SkipList跳跃表原理及代码实现

SkipList在leveldb以及lucence中都广为使用,是比较高效的数据结构。由于它的代码以及原理实现的简单性,更为人们所接受。我们首先看看SkipList的定义,为什么叫跳跃表? “ ...
  • u013011270
  • u013011270
  • 2013年12月18日 16:02
  • 24014

redis学习笔记(4)---跳表zskiplist

跳表  跳表(skiplist)是一种有序的数据结构,它通过在每个节点中维护多个指向其它节点的指针,来达到快速访问的目的。   跳表查找的时间复杂度平均为O(lgn),最坏情况下退化为单链表的O(n...
  • u012658346
  • u012658346
  • 2016年05月04日 19:05
  • 853

Redis内部数据结构详解之跳跃表(skiplist)

一、跳跃表简介 跳跃表是一种随机化数据结构,基于并联的链表,其效率可以比拟平衡二叉树,查找、删除、插入等操作都可以在对数期望时间内完成,对比平衡树,跳跃表的实现要简单直观很多。 以下是一个跳跃表的例图...
  • Acceptedxukai
  • Acceptedxukai
  • 2013年12月15日 14:09
  • 16395

跳表(SkipList)

最近在看leveldb的源码,看到核心的skiplist时发现自己浑浑噩噩的,本来就不太懂,.h文件里还竟是模板迭代器啥的,于是决定还是先吧思路理清楚,都提倡不要重复发明轮子,但只有熟悉轮子的制作过程...
  • uuuououlcz
  • uuuououlcz
  • 2015年07月27日 12:56
  • 216

跳表SkipList的原理和实现

最近看了一种数据结构叫做skipList,redis和levelDB都是用了它。Skip List是在有序链表的基础上进行了扩展,解决了有序链表结构查找特定值困难的问题,查找特定值的时间复杂度为O(l...
  • origin_lee
  • origin_lee
  • 2015年04月17日 09:43
  • 362
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:跳表(Skiplist)
举报原因:
原因补充:

(最多只允许输入30个字)