跳跃表skiplist简析

1.简述

跳跃表(skiplist)最初由William Pugh发表在ACM通讯上的论文《Skip
lists: a probabilistic alternative to balanced trees 》中,作者给出的定义是:跳表是在很多应用中有可能替代平衡树而作为实现方法的一种数据结构。跳跃列表的算法有同平衡树一样的渐进的预期时间边界,并且更简单、更快速和使用更少的空间。其实,跳表,顾名思义,跳跃的链表,跳表在链表的基础上增加了前向指针,对于链表而言,顺序查找的时间复杂度为线性时间,为了提高查找的效率,在有序链表的节点上增加额外的前向指针,可以通过额外的前向指针跨越链表中的若干个节点,那么到这里问题就来了,当然不是挖掘机哪家强啦。如何知道有序链表需要增加额外的前向指针,要增加多少额外的前向指针以及要跨越的节点数,在跳表的实现中,采用了随机化的技术,使得跳表的查找,插入,删除的平均时间复杂度为O(logn)

以下是一个跳跃表的例图(来自维基百科):

 

从图中可以看出跳跃表主要有以下几个部分构成:

<1> 表头head:负责维护跳跃表的节点指针

<2> 节点node:实际保存元素值,每个节点有一层或多层

<3> 层level:保存着指向该层下一个节点的指针

<4> 表尾tail:全部由null组成

跳跃表的遍历总是从高层开始,然后随着元素值范围的缩小,慢慢降低到低层。

2.跳表的基本原理

首先考虑有序链表如下,对于查找有序链表中的元素,只能用顺序查找的方法,在线性空间存储的有序元素中,折半查找的方法的时间复杂度为o(logn) ,跳表其实采用空间换时间的方法加速查找插入删除这些操作,跳表的性质如下

<1> 由很多层布局构成,level是经由过程必然的概率随机产生的

<2> 每一层都是一个有序的链表,默认是升序

<3> 最底层(Level 1)的链表包含所有元素。

<4> 若是一个元素呈如今Level i 的链表中,则它在Level i 之下的链表也都邑呈现。

<5> 每个节点包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素

下图列出了从有序链表转化为跳表的过程

3.跳表的实现

跳表作为基础的数据结构在一些开源的实现中使用非常广泛,包括leveldb,redis,都使用跳表作为基础的数据结构。redis中的有序集合就是基于跳表的基础结构实现的,leveldb中的memtable的实现就是基于跳表实现的 .在性能上,跳表完全可以比拟平衡树。二叉树可以用来表示字典和有序链表等抽象数据结构,当以随机顺序插入元素时,它们表现出非常好,但是连续插入有序元素时,会迅速退化导致非常糟糕的性能。跳表的表达比树更加直观,算法实现更加简单,比平衡树提供了常量因子速度提升,有效的空间效率,每个节点并不需要存储平衡或优先级信息

跳跃表的查找,插入和删除示意图如下

设定跳表的最大层数,每个节点的层数实现根据随机化算法实现,层越高,概率越小

跳表的search实现

跳表的insert实现

跳表的delete实现

参考:

Redis设计与实现

Skip lists: a probabilistic alternative to balanced trees

维基百科-跳跃表

时间: 2024-08-02 07:44:51

跳跃表skiplist简析的相关文章

跳跃表SkipList

SkipList在各种开源引擎中用处普遍,例如redis的sortedset容器.luence里面的索引字典等均用到了skiplist. 1.SkipList     在数据结构里面,我们知道有两种基本数据存储结构:数组和链表.它们均有其各自的特点,数组(特别是有序数组),可以进行快速查询,但不便于删除操作;链表,可以进行快速的增删操作,但是又不便于查询.那有没可能存在一种数据结构,结合两者各自的优点呢?     基于这样的思路,William Pugh这位马里兰大学的计算机教授,于1989年提

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

redis中并没有专门给跳跃表两个文件.在5.0.7的版本中,结构体的声明与定义.接口的声明在server.h中,接口的定义在t_zset.c中,所有开头为zsl的函数. 一.数据结构 单个节点: typedef struct zskiplistNode { //key,唯一 sds ele; //分值,可重复 double score; //后退指针 struct zskiplistNode *backward; //层 struct zskiplistLevel { //前进指针 struc

探索c#之跳跃表(SkipList)

阅读目录: 基本介绍 算法思想 演化步骤 实现细节 总结 基本介绍 SkipList是William Pugh在1990年提出的,它是一种可替代平衡树的数据结构. SkipList在实现上相对比较简单,比如在限定时间条件下,能非常轻松的实现SkipList,但却实现不了B树.红黑树.AVL树等,想一想单B树的删除,就要考虑非常多的细节.虽说SkipList简单,但性能却非常高,在平均情况下,其插入.删除.查找数据时间复杂度都是O(log(N)),其最坏情况下都为O(N),这点要低于平衡树. 由于

SkipList (跳跃表)解析及其实现

目录 导言 查找结点的效率如何提升? 什么是跳跃表? 跳跃表必须是完美的? 预备知识 抛硬币实验 模拟建表 操作解析 伪代码 代码实现 柔性数组 跳跃表的创建与销毁 跳跃表表头结构体定义 跳跃表结点结构体定义 建立跳跃表表头操作 操作解析 伪代码 代码实现 创建单个结点操作 操作解析 代码实现 销毁操作 操作解析 代码实现 插入操作 操作解析 时间复杂度 伪代码 代码实现 删除操作 操作解析 时间复杂度 伪代码 代码实现 查找操作 操作解析 伪代码 代码实现 时间复杂度分析 简单应用 跳跃字母表

学习笔记-Redis设计与实现-跳跃表

跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的. 跳跃表支持平均O(logN).最坏O(N)复杂度的节点查找,还可以通过顺序性操作来批量处理节点. Redis使用跳跃表作为有序结合键的底层实现之一,如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员(member)是比较长的字符串时,Redis就会使用跳跃表来作为有序集合见的底层实现. 5.1 跳跃表的实现 zskiplist结构,包含以下属性: header:

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

一.概述 跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树(关系型数据库的索引就是平衡树结构)相媲美,并且因为跳跃表的实现比平衡树要来得更为简单,所以有不少程序使用跳跃表来代替平衡树. Redis使用跳跃表作为"有序集合键"的底层实现之一,如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员是比较长的字符串时,Redis就会使用跳跃表来作为有序集合键的底层实现.

“跳跃表”简析

复杂度 空间复杂度: O(n) (期望) 跳跃表高度: O(logn)(期望) 查找:O(logn)(期望) 插入: O(logn)(期望) 删除:O(logn)(期望) 之所以在每一项后面都加一个“期望”,是因为跳跃表的复杂度分析是基于概率论的.有可能会产生最坏情况,不过这种概率极其微小. 顶层链表元素的确定方式 底层链表就是最初的链表,包含所有元素. we just like every node to be accessed sort of as quickly as possible,

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

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

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

SkipList在Leveldb以及lucence中都广为使用,是比较高效的数据结构.由于它的代码以及原理实现的简单性,更为人们所接受.首先看看SkipList的定义,为什么叫跳跃表? "Skip lists  are data structures  that use probabilistic  balancing rather  than  strictly  enforced balancing. As a result, the algorithms  for insertion  a