跳跃表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步,直到不再能选择出除最大最小元素以外的元素。
>>跳跃表的实现
通过在节点数据结构中维护多个指针,用空间换时间的方式实现高效率的查找。
跳跃表Skip List的原理和实现的更多相关文章
- 跳跃表Skip List的原理
1.二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果需要的是一个 ...
- 数据结构与算法(c++)——跳跃表(skip list)
今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...
- 跳跃表Skip List【附java实现】
skip list的原理 Java中的LinkedList是一种常见的链表结构,这种结构支持O(1)的随机插入及随机删除, 但它的查找复杂度比较糟糕,为O(n). 假如我们有一个有序链表如下,如果我们 ...
- 用golang实现常用算法与数据结构——跳跃表(Skip list)
背景 最近在学习 redis,看到redis中使用 了skip list.在网上搜索了一下发现用 golang 实现的 skip list 寥寥无几,性能和并发性也不是特别好,于是决定自己造一个并发安 ...
- 算法: skiplist 跳跃表代码实现和原理
SkipList在leveldb以及lucence中都广为使用,是比较高效的数据结构.由于它的代码以及原理实现的简单性,更为人们所接受. 所有操作均从上向下逐层查找,越上层一次next操作跨度越大.其 ...
- Redis(2)——跳跃表
一.跳跃表简介 跳跃表(skiplist)是一种随机化的数据结构,由 William Pugh 在论文<Skip lists: a probabilistic alternative to ba ...
- Skip List(跳跃表)原理详解与实现【转】
转自:http://dsqiu.iteye.com/blog/1705530 Skip List(跳跃表)原理详解与实现 本文内容框架: §1 Skip List 介绍 §2 Skip List 定义 ...
- Skip List(跳跃表)原理详解与实现
ref : https://dsqiu.iteye.com/blog/1705530 本文内容框架: §1 Skip List 介绍 §2 Skip List 定义以及构造步骤 §3 Skip ...
- 浅析SkipList跳跃表原理及代码实现
本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈“跳跃表”的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代 ...
随机推荐
- spring边边角角
我们在使用ssh框架的时候,很多人抱怨为什么之前都运行得好好的,第二天就报错了,我也是被这个问题纠结了很久. 我们来看看spring的配置文件: <?xml version="1.0& ...
- C#高级编程笔记 Day 3, 2016年9月 8日 抽象类
1.虚方法:把一个基类函数声明为 virtual,就可以在任何派生类中重写该函数. 2.在Java 中所有函数都是虚拟的,但是在C# 中,C# 要求在派生类的函数重写另一个函数时,要使用 overri ...
- linux各文件夹的作用
文章转载自:http://www.cnblogs.com/amboyna/archive/2008/02/16/1070474.html 精------------------------------ ...
- supervisor的配置
看了下文档,比较多.http://www.supervisord.org/ 抱着试试又不会怀孕的心态,trying,碰了几鼻子灰,记录如下, 方便大家 1. 安装 easy_install super ...
- jQuery Plugin Docs
遮罩:BlockUI 对话框:Dialog 输入框:Mask Plugin 下拉框: 1.自定义的实现思路:将下拉框的选项定义为全局变量(数组),在html中定义点击事件并将数组变量转给响应函数,每次 ...
- ios swfit 由继承UIButton了解类的构造方法
最近需要建立UIButton的子类. 先看一看swfit中继承父类构造方法的条件: Rule1 1“If your subclass doesn’t define any designated ini ...
- C# 静态函数调用窗体控件
回调函数方法是静态函数,需要调用窗体控件,赋值或取值. 定义 public static Form1 mainFrm; mainFrm = this; public partial class F ...
- 3.nodejs权威指南--文件
1. 文件 1.1 读写整个文件 1.1.1 读 var fs = require('fs'); fs.readFile('./test.txt',function(err,data){ if(err ...
- ffmpeg-20160520-git-bin
ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...
- Maven 3.3.3 Win10环境下的使用实例(下)
这一篇文章将介绍如何在 Eclipse 中使用 Maven. 我们以 Eclipse Java EE 版本为例,首先要对 IDE 进行一些设置: JDK 环境 Maven 的本地安装路径 Maven ...