阅读目录:

  1. 基本介绍
  2. 算法思想
  3. 演化步骤
  4. 实现细节
  5. 总结

基本介绍

SkipList是William Pugh在1990年提出的,它是一种可替代平衡树的数据结构。 SkipList在实现上相对比较简单,比如在限定时间条件下,能非常轻松的实现SkipList,但却实现不了B树、红黑树、AVL树等,想一想单B树的删除,就要考虑非常多的细节。虽说SkipList简单,但性能却非常高,在平均情况下,其插入、删除、查找数据时间复杂度都是O(log(N)),其最坏情况下都为O(N),这点要低于平衡树。
SkipList依赖随机生成数以一定概率来保持数据在树上的平衡分布,所以SkipList也属于概率算性的数据结构,和之前介绍的BoolFilter属于一个类型C#之布隆过滤器(Bloom filter)

算法思想

举个例子,楼主逛完街要回张江玉兰香苑,如果从人民广场做公交车回去,要路过非常多的站:

想想这么远的路程,多悲惨(在大数据情况下找对应项同样的问题),相较来说坐地铁就快很多,然后到广兰路换程。 这就是SkipList最核心的思想非常简单。 现在路线变成:


因为可以一次跨越很多不需要的站,所以就快了很多。如果可以搭朋友顺风车的话,变成:

这个图就非常接近SkipList的结构及思想了。

演化步骤

大致了解怎么回事了、看具体怎么实现。 首先我们忘记树、图等高级概念及结构,回到我们刚学到链表的时候。 再看上面的回家路线图,我们把最下面一层当成一个链表,每个节点(站)指针指向下一个节点(站)。
单个有序链表:

按照传统的操作有序链表的做法,如果需要查找其中一条数据,需要顺序遍历。 按照地铁的思路,如果给一部分的节点增加个指向后面的节点指针,假设一半节点增加,最多遍历[n/2]+1次即可找到任意节点。这里把18、23、33、40、47节点都多增加个指针指向后面的节点:

以此类推,继续增加3、4个等更多的指针,使其指向更远的后方节点,这样可以更好的提高查询效率。 3个节点的情况:

如果理想情况下查找,就类似二分查找了。 SkipList通过随机数(丢硬币决定)在插入节点时,随机判定该节点应该有多少个执行后续节点的指针。 有几个执行后面节点指针,就是在第几层,比如上图18存在3个指针指向后面,它就在第三层,23有2个指针就在第二层。

实现细节

搜索

在同一层查找节点时和普通有序链表一样,顺序向后查找,查到返回,否则进入下一层继续向后查找。比如查找35,会从最顶层搜索比较18、相等返回,大于比较40继续下一层找,比较1、23、33、40后继续下一层,比较33、35正确返回、否则不存在。

更新

搜索到值后更新:

        SkipListNode<TKey, TValue> position;
bool found = search(key, out position);
if(found)
position.value = value;

插入

插入时,如果值存在则更新,不存在插入。 如上图,假如要插入29,需要先查找到27插入到后面,如果扔硬币后得到3,那么依次增加指向后面节点的指针。

随机数

也称丢硬币做法。

       Random generator = new Random();
int levels = ;
while (generator.NextDouble() < 0.5&&levels<=maxlevel)
levels++;
return levels;

删除同插入一样,如果找到,调整相对应的指针顺序,然后删除节点。

总结

由于skipList的高效及维护简单,所以很多大数据系统中在维护有序列表是都会使用SkipList。比如LevelDB在内存中暂存数据的结构MemTable是使用SkipList实现的,Redis在Sorted Set数据结构时也采用的是SkipList,还有Lucene中同样采用SkipList来对倒排列表进行快速查找。

关于就算法的实现, 可参考https://github.com/kencausey/SkipList

探索C#之系列导航

探索c#之跳跃表(SkipList)的更多相关文章

  1. Redis数据结构之跳跃表-skiplist

    在Redis中,zset是一个复合结构: 使用hash来存储value和score的映射关系 使用跳跃表来提供按照score进行排序的功能,同时可以指定score范围来获取value列表 结构 zse ...

  2. redis 5.0.7 源码阅读——跳跃表skiplist

    redis中并没有专门给跳跃表两个文件.在5.0.7的版本中,结构体的声明与定义.接口的声明在server.h中,接口的定义在t_zset.c中,所有开头为zsl的函数. 一.数据结构 单个节点: t ...

  3. 跳跃表 SkipList【数据结构】原理及实现

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

  4. 探索Skip List (跳跃表)

    附William Pugh的论文 Skip Lists: A Probabilistic Alternative to Balanced Trees 写在前面 以下内容针对的是Skip List的插入 ...

  5. redis 系列7 数据结构之跳跃表

    一.概述 跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树(关系型数据库的索引就是平衡树 ...

  6. [Redis]Redis的设计与实现-链表/字典/跳跃表

    redis的设计与实现:1.假如有一个用户关系模块,要实现一个共同关注功能,计算出两个用户关注了哪些相同的用户,本质上是计算两个用户关注集合的交集,如果使用关系数据库,需要对两个数据表执行join操作 ...

  7. Redis底层探秘(二):链表和跳跃表

    链表简介 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地跳转链表的长度. 作为一种常用数据结构,链表内置在很多高级的编程语言里面,因为Redis使用C语言并没有内 ...

  8. Redis(2)——跳跃表

    一.跳跃表简介 跳跃表(skiplist)是一种随机化的数据结构,由 William Pugh 在论文<Skip lists: a probabilistic alternative to ba ...

  9. 【Redis】跳跃表原理分析与基本代码实现(java)

    最近开始看Redis设计原理,碰到一个从未遇见的数据结构:跳跃表(skiplist).于是花时间学习了跳表的原理,并用java对其实现. 主要参考以下两本书: <Redis设计与实现>跳表 ...

随机推荐

  1. Js(DOM) 和Jq 对象的相互转换

    JQuery 对象不能使用DOM对象中的方法,同样,Dom对象 不能使用JQuery 中的方法,但有时候 ,我们不得不使用JQuery的方法或者 Dom对象的方法,该怎么办呢? 下面介绍一下 jq对象 ...

  2. 如何托管ASP.NET Core应用到Windows Service中

    (此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:正在构思一个中间件的设计,考虑是否既可以使用最新的技术,也可以兼顾传统的部署模式.所以有 ...

  3. a 标签中加 onclick事件,根据事件中的校验情况来决定是否执行a标签的链接

    a 标签中加 onclick方法后,先执行onclick方法,在去执行a标签href下属性对应的动作,如果不想执行href属性下动作需要用false作为返回值. <a href="ht ...

  4. Spring 使用 SLF4J代替 Commons Logging 写日志 异常

    项目的日志更换成slf4j和logback后,发现项目无法启动.错误提示 Caused by: java.lang.NoClassDefFoundError: Lorg/apache/commons/ ...

  5. 读取web项目properties文件路径 解决tomcat服务器找不到properties路径问题

    1.需求:有时候我们产品经理给我们的需求是会不断变化的,例如数量是1000现在变成500,我们不可以去改代码吧,这样很麻烦,所以就可以改配置文件properties(这个数据库链接一样),当然也有js ...

  6. 深入理解JavaScript运行机制

    深入理解JavaScript运行机制 前言 本文是写作在给团队新人培训之际,所以其实本文的受众是对JavaScript的运行机制不了解或了解起来有困难的小伙伴.也就是说,其实真正的原理和本文阐述的并不 ...

  7. WebViewJavascriptBridge使用说明(iOS)

    由于现在很多产品都是有安卓版跟ios版,就意味着同一样东西要出两套,由两组人去完成,不仅增加了开发成本,也大大加剧了维护成本.聪明的coder想出了跨平台的思路,用html写页面,分别用webview ...

  8. 二分图&网络流&最小割等问题的总结

    二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...

  9. Excel转Html

    项目结构: 这是一个maven项目,主函数在Client类里面 当运行程序的后,控制台情况: 当我们刷新了test.html文件后,用浏览器打开效果: 说一下这个过程的设计思路: 1.读取excel文 ...

  10. STM32之输入捕获以及小小应用(库)

    五一之际,先祝大家五一快乐.其实快乐很简单,工作的人有假放,学习的人也有假放,像我,有假放才有更多的时间学自己想学的东西.51假期学51,可惜没有32假期呀.好了..言归正传,大家听过吸星大法吧..在 ...