讲讲跳跃表(Skip Lists)
跳跃表(Skip Lists)是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。在大部分情况下,跳跃表的效率可以和平衡树相媲美,并且在实现上比平衡树要更为简单,因而得到了广泛的应用。

如上图所示,是一个跳跃表的示例。由此可以看出跳跃表的几个特点:
有序性,如上图中各节点呈递增趋势;
跳跃表由多个层组成;
跳跃表的第一层始终包含所有元素;
如果某个元素位于第 i 层,那该层一下的所有层也会包含此元素。
既然是链表的一种,那在实现时,固然要考虑插入、删除、查找等几个主要方法,下面来一一解析。
查找
要查找一个元素,应从顶层开始,自顶向下查找,又因为其有序性,因此与平衡树上的查找其实很类似。
以之前的图为例,要搜索 12,从顶层为入口,步骤大致如下:
从 L3 的第一个节点查询后一个节点 21,发现比 12 大,跳至下一层;
从 L2 的第一个节点查询后一个节点 9,比 12 小,因此继续向后;
继续查询 L2 的下一个节点 21,比 12 大,跳至下一层;
从 L1 的第一个节点开始查询,直至 17 时发现比 12 大,再次调至下一层;
从 L0 的第一个节点开始查询,最终发现 12 这个节点,查询结束。
如果要查询的节点在 L0 中都不存在,则应返回并告知“该节点不存在”。
插入
要插入一个节点,不难想象首先需要查询插入的位置,因此首先其实是类似的执行一次查询。然后视情况定是做替换操作还是新增节点。插入的时候要利用一个随机算法来获取该元素要插入的层高,并根据“如果某个元素位于第 i 层,那该层一下的所有层也会包含此元素”这一特性,在要插入层和以下层中都要插入这个新元素。最后还要注意维护层高。以下是插入过程的一个示例:

删除
删除的第一步和插入很类似,首先要执行查找过程。如果查找到,则将该元素删除。这里也必须注意“如果某个元素位于第 i 层,那该层一下的所有层也会包含此元素”这一特性。最后还要注意维护层高。
性能上,跳跃表支持平均 O(log N)、最坏 O(N) 复杂度的节点查找,还可以通过顺序性操作来批量处理节点。
代码实现在网上有很多代码可以参考,且实现方法和细节也不尽相同,因此不在这里提及,而是更多的关注原理。有时候掌握基础与原理其实更为重要。
本文的插图来自于 William Pugh 关于跳跃表的论文《Skip Lists: A Probabilistic Alternative to Balanced Trees》,其中分析了跳跃表的实现及性能,值得研读。
——————————
推荐阅读:
讲讲跳跃表(Skip Lists)的更多相关文章
- 跳跃表Skip List的原理和实现
>>二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果 ...
- 数据结构与算法(c++)——跳跃表(skip list)
今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...
- 跳跃表Skip List的原理
1.二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果需要的是一个 ...
- 跳跃表Skip List【附java实现】
skip list的原理 Java中的LinkedList是一种常见的链表结构,这种结构支持O(1)的随机插入及随机删除, 但它的查找复杂度比较糟糕,为O(n). 假如我们有一个有序链表如下,如果我们 ...
- 用golang实现常用算法与数据结构——跳跃表(Skip list)
背景 最近在学习 redis,看到redis中使用 了skip list.在网上搜索了一下发现用 golang 实现的 skip list 寥寥无几,性能和并发性也不是特别好,于是决定自己造一个并发安 ...
- Redis(2)——跳跃表
一.跳跃表简介 跳跃表(skiplist)是一种随机化的数据结构,由 William Pugh 在论文<Skip lists: a probabilistic alternative to ba ...
- skip跳跃表的实现
skiplist介绍 跳表(skip List)是一种随机化的数据结构,基于并联的链表,实现简单,插入.删除.查找的复杂度均为O(logN).跳表的具体定义, 跳表是由William Pugh发明的, ...
- skip list跳跃表实现
跳表(skip List)是一种随机化的数据结构,基于并联的链表,实现简单,插入.删除.查找的复杂度均为O(logN).跳表的具体定义,跳表是由William Pugh发明的,这位确实是个大牛,搞出一 ...
- Skip List(跳跃表)原理详解与实现【转】
转自:http://dsqiu.iteye.com/blog/1705530 Skip List(跳跃表)原理详解与实现 本文内容框架: §1 Skip List 介绍 §2 Skip List 定义 ...
随机推荐
- mysql数据库的基本操作:索引、视图,导入和导出,备份和恢复
1.索引: 索引是一种与表有关的结构,它的作用相当于书的目录,可以根据目录中的页码快速找到所需的内容. 当表中有大量记录时,若要对表进行查询,没有索引的情况是全表搜索:将所有记录一一取出,和查询条件进 ...
- C语言复习1_变量与数据类型
变量命名规则: 1.变量名的首字母或下划线(不能是其他特殊符号) 2.变量名的其他字母包含下划线.数字 和字母 3.不能使用关键字 基本数据类型 分为数值型和非数值型,其中数值型分为整型和非整型 整型 ...
- 2sat
之前做的两发 https://vjudge.net/problem/UVALive-3211 #include<cstdio> #include<cstring> #inclu ...
- 多个router和多个network
一般搭建成功了opentack后,都会按照文档的这样创建网络 Scenario 1: one tenant, two networks, one router Scenario 2: two tena ...
- 算法与数据结构(八) AOV网的关键路径(Swift版)
上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的, ...
- Spring AOP实现 Bean字段合法性校验
使用SpringAop 验证方法参数是否合法 先定义两个注解类ValidateGroup 和 ValidateFiled ValidateGroup .java package com.zf.an ...
- [Swift]LeetCode652. 寻找重复的子树 | Find Duplicate Subtrees
Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...
- CentOS7 Linux中通过加密grub防止黑客通过单用户系统破解root密码
如何防止别人恶意通过单用户系统破解root密码,进入系统窃取数据? 给grub加密,不让别人通过grub进入单用户. 17.3.1 基于centos6进行grub加密 [root@63 ~]# gr ...
- TensorFlow tf.gradients的用法详细解析以及具体例子
tf.gradients 官方定义: tf.gradients( ys, xs, grad_ys=None, name='gradients', stop_gradients=None, ) Cons ...
- Spring mvc参数类型转换
1,需求 有时候我们接收到的参数为String类型的,但是我们需要将它们转化为其他类型的如:date类型,枚举类型等等,spring mvc为我们提供了这样的功能. 2,配置文件 在springmvc ...