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

如上图所示,是一个跳跃表的示例。由此可以看出跳跃表的几个特点:

  • 有序性,如上图中各节点呈递增趋势;

  • 跳跃表由多个层组成;

  • 跳跃表的第一层始终包含所有元素;

  • 如果某个元素位于第 i 层,那该层一下的所有层也会包含此元素。

既然是链表的一种,那在实现时,固然要考虑插入、删除、查找等几个主要方法,下面来一一解析。

查找

要查找一个元素,应从顶层开始,自顶向下查找,又因为其有序性,因此与平衡树上的查找其实很类似。

以之前的图为例,要搜索 12,从顶层为入口,步骤大致如下:

  1. 从 L3 的第一个节点查询后一个节点 21,发现比 12 大,跳至下一层;

  2. 从 L2 的第一个节点查询后一个节点 9,比 12 小,因此继续向后;

  3. 继续查询 L2 的下一个节点 21,比 12 大,跳至下一层;

  4. 从 L1 的第一个节点开始查询,直至 17 时发现比 12 大,再次调至下一层;

  5. 从 L0 的第一个节点开始查询,最终发现 12 这个节点,查询结束。

如果要查询的节点在 L0 中都不存在,则应返回并告知“该节点不存在”。

插入

要插入一个节点,不难想象首先需要查询插入的位置,因此首先其实是类似的执行一次查询。然后视情况定是做替换操作还是新增节点。插入的时候要利用一个随机算法来获取该元素要插入的层高,并根据“如果某个元素位于第 i 层,那该层一下的所有层也会包含此元素”这一特性,在要插入层和以下层中都要插入这个新元素。最后还要注意维护层高。以下是插入过程的一个示例:

删除

删除的第一步和插入很类似,首先要执行查找过程。如果查找到,则将该元素删除。这里也必须注意“如果某个元素位于第 i 层,那该层一下的所有层也会包含此元素”这一特性。最后还要注意维护层高。

性能上,跳跃表支持平均 O(log N)、最坏 O(N) 复杂度的节点查找,还可以通过顺序性操作来批量处理节点。

代码实现在网上有很多代码可以参考,且实现方法和细节也不尽相同,因此不在这里提及,而是更多的关注原理。有时候掌握基础与原理其实更为重要。

本文的插图来自于 William Pugh 关于跳跃表的论文《Skip Lists: A Probabilistic Alternative to Balanced Trees》,其中分析了跳跃表的实现及性能,值得研读。

——————————

推荐阅读:

说框架设计思路

老王说架构

一次性讲透Activiti工作流

FaaS技术架构

华为Java编程军规,每季度代码验收标准

讲讲跳跃表(Skip Lists)的更多相关文章

  1. 跳跃表Skip List的原理和实现

    >>二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果 ...

  2. 数据结构与算法(c++)——跳跃表(skip list)

    今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...

  3. 跳跃表Skip List的原理

    1.二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果需要的是一个 ...

  4. 跳跃表Skip List【附java实现】

    skip list的原理 Java中的LinkedList是一种常见的链表结构,这种结构支持O(1)的随机插入及随机删除, 但它的查找复杂度比较糟糕,为O(n). 假如我们有一个有序链表如下,如果我们 ...

  5. 用golang实现常用算法与数据结构——跳跃表(Skip list)

    背景 最近在学习 redis,看到redis中使用 了skip list.在网上搜索了一下发现用 golang 实现的 skip list 寥寥无几,性能和并发性也不是特别好,于是决定自己造一个并发安 ...

  6. Redis(2)——跳跃表

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

  7. skip跳跃表的实现

    skiplist介绍 跳表(skip List)是一种随机化的数据结构,基于并联的链表,实现简单,插入.删除.查找的复杂度均为O(logN).跳表的具体定义, 跳表是由William Pugh发明的, ...

  8. skip list跳跃表实现

    跳表(skip List)是一种随机化的数据结构,基于并联的链表,实现简单,插入.删除.查找的复杂度均为O(logN).跳表的具体定义,跳表是由William Pugh发明的,这位确实是个大牛,搞出一 ...

  9. Skip List(跳跃表)原理详解与实现【转】

    转自:http://dsqiu.iteye.com/blog/1705530 Skip List(跳跃表)原理详解与实现 本文内容框架: §1 Skip List 介绍 §2 Skip List 定义 ...

随机推荐

  1. 批处理修改IP

    1. 单次修改IP,批处理文件 newIP.bat @echo =========== Changing to IP : 222.192.41.%1 netsh interface ip set ad ...

  2. 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑)

    背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮币”.为了增加趣味性,帮帮币“掉落”之后所有用户都可以“捡取”,谁先捡到 ...

  3. Java语言

    Java语言基础教程 本文将放入菜单栏中方便学习,记得点赞哦! Java分为3个体系,为JavaSE,JavaEE,JavaME,是一种面向对象的程序设计语言,记住Oracle公司收购了 Sum公司, ...

  4. Oracle客户端、服务的安装及干净卸载Oracle

    软件下载地址: 链接:https://pan.baidu.com/s/1Sluf890eNuaV8muL55eO2w 提取码:oez7 服务端因文件过大,所以分了两个文件压缩包,下载后将内容解压后放置 ...

  5. [Swift]LeetCode34. 在排序数组中查找元素的第一个和最后一个位置 | Find First and Last Position of Element in Sorted Array

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

  6. [Swift]LeetCode347. 前K个高频元素 | Top K Frequent Elements

    Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [ ...

  7. [Swift]LeetCode794. 有效的井字游戏 | Valid Tic-Tac-Toe State

    A Tic-Tac-Toe board is given as a string array board. Return True if and only if it is possible to r ...

  8. three.js全景漫游实践

    Hello 小伙伴们,如果觉得本文还不错,记得给个 star , 小伙伴们的 star 是我持续更新的动力!GitHub 地址 简介 全景图分两种 由六张正方形图片组成的SkyBox 一整张的宽高比为 ...

  9. [Abp 源码分析]十四、DTO 自动验证

    0.简介 在平时开发 API 接口的时候需要对前端传入的参数进行校验之后才能进入业务逻辑进行处理,否则一旦前端传入一些非法/无效数据到 API 当中,轻则导致程序报错,重则导致整个业务流程出现问题. ...

  10. 关闭mac的SIP + 一定有用的删除mac自带ABC的方法

    如果你被这ABC输入法弄得很是不开心.那就看看吧!!!亲测一定有效. mac 关闭系统完整性保护 SIP(System Integrity Protection) 重启系统 按住 command+R ...