跳跃表Skip List的原理和实现

二分查找和AVL树查找

二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存。这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了。
如果需要的是一个能够进行二分查找,又能快速添加和删除元素的数据结构,首先就是二叉查找树,二叉查找树在最坏情况下可能变成一个链表,
于是就出现了平衡二叉树,根据平衡的算法不同有AVL树,B-Tree,B+Tree,红黑树等,但是AVL树实现起来比较复杂,
平衡操作较难理解,这时候就可以用SkipList跳跃表结构。

什么是跳跃表

Skip list(跳表)是一种可以代替平衡树的数据结构,默认是按照Key值升序的。Skip list让已排序的数据分布在多层链表中,以0-1随机数决定一个数据的向上攀升与否,通过“空间来换取时间”的一个算法,在每个节点中增加了向前的指针,在插入、删除、查找时可以忽略一些不可能涉及到的结点,从而提高了效率。
在Java的API中已经有了实现:分别是
ConcurrentSkipListMap(在功能上对应HashTable、HashMap、TreeMap) ;
ConcurrentSkipListSet(在功能上对应HashSet)
跳跃表以有序的方式在层次化的链表中保存元素, 效率和AVL树媲美 —— 查找、删除、添加等操作都可以在O(LogN)时间下完成, 并且比起二叉搜索树来说, 跳跃表的实现要简单直观得多。

从图中可以看到, 跳跃表主要由以下部分构成:

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

跳跃表的构造

一个跳表,应该具有以下特征:

  • 一个跳表应该有几个层(level)组成;
  • 跳表的第一层包含所有的元素;
  • 每一层都是一个有序的链表;
  • 如果元素x出现在第i层,则所有比i小的层都包含x;
  • 第i层的元素通过一个down指针指向下一层拥有相同值的元素;
  • 在每一层中,-1和1两个元素都出现(分别表示INT_MIN和INT_MAX);
  • Top指针指向最高层的第一个元素。

以下面的链表为例演示如何构造一个跳跃表:

构造一个3层的跳跃表:

Skip List构造步骤:
1、给定一个有序的链表。
2、选择连表中最大和最小的元素,然后从其他元素中按照一定算法(随机)随即选出一些元素,将这些元素组成有序链表。这个新的链表称为一层,原链表称为其下一层。
3、为刚选出的每个元素添加一个指针域,这个指针指向下一层中值同自己相等的元素。Top指针指向该层首元素
4、重复2、3步,直到不再能选择出除最大最小元素以外的元素。 

跳跃表的实现

 通过在节点数据结构中维护多个指针,用空间换时间的方式实现高效率的查找。

时间: 2024-10-28 10:53:38

跳跃表Skip List的原理和实现的相关文章

算法: skiplist 跳跃表代码实现和原理

SkipList在leveldb以及lucence中都广为使用,是比较高效的数据结构.由于它的代码以及原理实现的简单性,更为人们所接受. 所有操作均从上向下逐层查找,越上层一次next操作跨度越大.其实现是典型的空间换时间. Skip lists are data structures that use probabilistic balancing rather than strictly enforced balancing. As a result, the algorithms for

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

本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈"跳跃表"的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢.     跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类的AVL树

跳跃表的分析与实现

----<大规模分布式存储系统:原理解析与架构实战>读书笔记 在了解了 Bitcask存储模型后,又开始研究LSM树存储引擎.LSM在实现的过程中使用了一个很有意思的数据结构:跳跃表.之前在<算法导论公开课>中听过这一节.当时感觉这种结构和二叉树简直是殊途同归,但是一直没有亲自动手实现过.这次又遇到了,就来实现试试看.话说跳跃表和各种平衡树一样,都是用来加速查询的.要随手实现一个B树不容易,但是实现一个跳跃表就简单很多. 跳跃表的简单介绍 跳跃列表一个有序链表,按层建造的.底层是一

大家好,问大家一个问题,关于跳跃表的

问题描述 跳跃表是怎么查找的,具体的过程是什么呢?请帮忙解释下,谢谢 解决方案 我就不贴图了,你可以看我的这篇文章跳跃表(Skip List)http://deepfuture.iteye.com/blog/954342解决方案二:跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类的AVL树,红黑树等要低得多,这使得其无论是在理解还是在推广性上

jsp中form表单的工作原理?

问题描述 jsp中form表单的工作原理? 1.为什么form表单可以提交到下个页面并且传值? 2.在form表单jsp页面转换成servlet页面后,里面只有一堆out.print().怎么不见跳转,或者传值类的东西? 求各位大神解惑,谢谢大家 解决方案 是HTML标签,是浏览器所识别的,所以浏览器会自动识别这个东西,知道是http请求服务器的,并通过tcp/ip协议传输,和servlet没有关系,jsp是可以在html中嵌套java代码并最终生成servlet的.

[redis设计与实现][4]基本数据结构——跳跃表

Redis使用跳跃表和字典共同来实现有序集合键(sorted set). 定义: 跳跃表节点: [cce lang="c"] typedef struct zskiplistNode { //成员对象 robj *obj; //分值 double score; //后退指针 struct zskiplistNode *backward; //层结构 struct zskiplistLevel { //前进指针 struct zskiplistNode *forward; //跨度 un

Redis的数据类型和抽象概念介绍

原文链接 译者:carvin Redis 不是一个 简单的 key-value 存储,实际上它是一个数据结构服务器,它支持不同类型的值.也就是说,在传统的key-value存储中,你将一个字符串的key关联到一个字符串的值上:而在Redis中,值不仅仅局限于简单的字符串,还同时支持其他复杂的数据结构.以下的列表是所有Redis支持的数据结构,在这篇指南中将一一介绍: 二进制安全的字符串. 列表[Lists]: 按照插入顺序排序的字符串元素集合.它们基于链表实现. 集合[Sets]: 唯一的.无序

Java 性能调优指南之 Java 集合概览

[编者按]本文作者为拥有十年金融软件开发经验的 Mikhail Vorontsov,文章主要概览了所有标准 Java 集合类型.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正文: 本文将概览所有标准的 Java 集合类型.我们将按照它们可区分的属性与主要用例进行分类.除此之外,我们还将穷举在不同集合类型之间进行数据转换的方法. 数组(Arrays) 数组是 Java 语言内置的唯一集合类型,尤其擅长处理预先知道数量上限的元素集.java.util.Arrays 包含了许多用于处

基于Redis 千万级用户排行榜最佳实践

基于Redis 千万级用户排行榜最佳实践 前言 Redis 是一个开源的,内存中的数据结构存储系统,可以用作数据库.缓存和消息队列中间件.它支持多种类型的数据结构,如 字符串(string), Hash, 列表(List), 集合(Set), 有序集合(Sorted Set) . 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(Transactions) 和不同级别的 磁盘持久化(Persistence), 并