讲讲跳跃表(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 定义 ...
随机推荐
- Android找回密码功能 手机找回、邮箱找回
找回密码功能设计:https://blog.csdn.net/qq_33472765/article/details/82287404?utm_source=blogxgwz0 手机找回:https: ...
- hibernate的session的增删查改
一.增 //******************增加****************** Customer c = new Customer(); c.setCust_name("阿里云&q ...
- 访问不了虚拟机 ubuntu中的myql,解决方案
============================================================== 1. 现象 2. 原因分析 2.1 访问虚拟机中的mysql的前提: 你的 ...
- 几个比较常用的jar包
implementation 'com.android.support:recyclerview-v7:26+'implementation 'org.greenrobot:eventbus:3.1. ...
- 谈一谈从 Delphi 2009 之后就支援的重要功能 – 泛型 (Generic)
前言 在C++的语言基础当中,除了物件导向.事件驱动的概念之外,模版设计(Template)也是非常重要的一环.然而,C++的开发人员能够善用模版设计的并不多.模版设计这个好物,一般还有一个名称,就是 ...
- [Swift]LeetCode94. 二叉树的中序遍历 | Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [1,null,2,3] ...
- [Swift]LeetCode419. 甲板上的战舰 | Battleships in a Board
Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, ...
- [Swift]LeetCode838. 推多米诺 | Push Dominoes
There are N dominoes in a line, and we place each domino vertically upright. In the beginning, we si ...
- [Swift]LeetCode1029. 两地调度 | Two City Scheduling
There are 2N people a company is planning to interview. The cost of flying the i-th person to city A ...
- 注解式controller开发,action找不到controller???
Spring这一列列的 , 配置是真的多,学完我都忘啦 那个配置是干什么的了. 这里我遇到的问题是 我前台 使用action请求controller中的方法时,却找不到 报错404. 首先你路径 ...