跳跃表Skip List【附java实现】
skip list的原理
Java中的LinkedList是一种常见的链表结构,这种结构支持O(1)的随机插入及随机删除, 但它的查找复杂度比较糟糕,为O(n)。
假如我们有一个有序链表如下,如果我们想找到值为59的节点,需要查找7次。怎么提高查询效率呢?通常的做法是使用二分法,但LinkedList的随机访问时间复杂度同样为O(n),因此朴素的二分法并不适用。那怎么办呢?
我们可以在节点中增加额外的跳跃节点,如下:
这样我们可以根据跳跃节点查询,只需要查找3次。至于查询47,我们先根据跳跃节点来查询,于是在节点22上,它的跳跃指针指向55,比47要大,因此我们可以知道47可能会存在于节点22和节点55之间,这时候再根据普通的指针顺序查找。一共需要查找5次。
随着节点的增多,我们的链表结构会变成这样:
跳跃节点的密度为普通节点的一半,理想情况下,这种结构会比原结构查询性能提高一倍。有没有办法再提高呢?有,我们可以在这基础上再加一层新的跳跃节点,这层节点的密度又为第一层跳跃节点的一半。
更直观点:
进一步限定每一层的跳跃节点都由它下一层的跳跃节点中产生,因此,我们的跳跃表最终看起来像是这样的。
我们不区分每一层是原节点还是跳跃节点,将最底下的那一层节点称为第一层节点,第一层节点上面为第二层节点,然后第三层...以此类推。
这样的结构,称之为跳跃表。假设每一层的节点数为下一层的一半,那么时间复杂度为O(logn)。
实现方案
如上所述,skip list是具有分层结构的有序链表,那每一层的节点应该如何产生呢?
我们可以在新增元素的时候使用随机方法决定这个元素有几层节点。设定该元素有且只有一层节点概率为1/2,有且只有两层节点概率为1/4,有且只有三层节点概率为1/8,以此类推。然后触发随机事件,当概率为1/2的事件发生时该元素有一层节点,概率为1/2的事件发生时该元素有两层节点...另外,我们限定一个跳跃表应该具有一个最大的层数限制。
假设一个跳跃表最大层数限制为4,那么可以设定一个整数区间为[1, 2^(4-1)],即[1, 8]。然后取一个1~8的随机数,当落在[5, 8]区间时有一层节点,落在[3, 4]区间时有两层节点,落在[2, 2]区间时有三层,落在[1, 1]上时有四层。由于我们设定了跳跃表的最大层数,因此概率等式1 = 1/2 + 1/4 + 1/8 + ... + 1/2^n的最后两项相同。
Java实现
跳跃表Skip List【附java实现】的更多相关文章
- 跳跃表Skip List的原理和实现
>>二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果 ...
- 跳跃表Skip List的原理
1.二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果需要的是一个 ...
- 数据结构与算法(c++)——跳跃表(skip list)
今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...
- 用golang实现常用算法与数据结构——跳跃表(Skip list)
背景 最近在学习 redis,看到redis中使用 了skip list.在网上搜索了一下发现用 golang 实现的 skip list 寥寥无几,性能和并发性也不是特别好,于是决定自己造一个并发安 ...
- Redis(2)——跳跃表
一.跳跃表简介 跳跃表(skiplist)是一种随机化的数据结构,由 William Pugh 在论文<Skip lists: a probabilistic alternative to ba ...
- 讲讲跳跃表(Skip Lists)
跳跃表(Skip Lists)是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树相媲美,并且在实现上比平衡树要更为 ...
- skip跳跃表的实现
skiplist介绍 跳表(skip List)是一种随机化的数据结构,基于并联的链表,实现简单,插入.删除.查找的复杂度均为O(logN).跳表的具体定义, 跳表是由William Pugh发明的, ...
- skip list跳跃表实现
跳表(skip List)是一种随机化的数据结构,基于并联的链表,实现简单,插入.删除.查找的复杂度均为O(logN).跳表的具体定义,跳表是由William Pugh发明的,这位确实是个大牛,搞出一 ...
- 基于跳跃表的 ConcurrentSkipListMap 内部实现(Java 8)
我们知道 HashMap 是一种键值对形式的数据存储容器,但是它有一个缺点是,元素内部无序.由于它内部根据键的 hash 值取模表容量来得到元素的存储位置,所以整体上说 HashMap 是无序的一种容 ...
随机推荐
- windows 20003 扩展安装后不成功的原因
windows扩展如果安装不成功(PHP扩展)很大的可能就是那个DLL的权限不够.需要分配:AdministratorAuthenticater UsersIIS_WPGSYSTEMUsers
- 简单的SqlHelper
namespace Login { class SqlHelper { //连接数据库的字符串 //static string dataConnection = "server=***-PC ...
- 【深度解析】Google第二代深度学习引擎TensorFlow开源
作者:王嘉俊 王婉婷 TensorFlow 是 Google 第二代深度学习系统,今天宣布完全开源.TensorFlow 是一种编写机器学习算法的界面,也可以编译执行机器学习算法的代码.使用 Tens ...
- java设计模式——单例(Singleton)模式
在某些场景,你需要找到一个承担职责的对象,并且这个对象是他所属类的唯一实例.此时可以使用单例模式. 单例模式的意图是为了确保一个类有且仅有一个实例,并为他提供一个全局的访问点.创建一个担当独一无二角色 ...
- linxu 挂载分区
1. 添加新硬盘 设置 -> Storage -> SATA控制器->右击,选择“添加虚拟硬盘” 然后,根据需求创建合适的硬盘 2. 重启虚拟机 查看现有系统的磁盘空间 sudo f ...
- U盘美化(更换U盘logo和页面背景软件)
U盘内新建txt文本后,输入 [autorun] ICON=ooopic_1459309050.ico 保存的文件名包括后缀更改为autorun.inf 必须为icon图标
- php 钩子函数原理 解析
目前对钩子的理解:<转载:http://www.cnblogs.com/del/archive/2008/02/25/1080825.html> 譬如我们用鼠标在某个窗口上双击了一次, 或 ...
- Android各种访问权限Permission详解
原文:http://jingyan.baidu.com/article/afd8f4de4688af34e386e976.html 在Android的设计中,资源的访问或者网络连接,要得到这些服务都需 ...
- Android 中文 API (29) —— CompoundButton
前言 本章内容是android.widget.CompoundButton,翻译来自德罗德,再次感谢德罗德 !期待你一起参与Android API 的中文翻译,联系我over140@gmail.com ...
- iOS9 以上的真机调试 不用证书
具体流程如下: 首次使用AppleID 的注意事项: 要在设置中 进行 如下操作 设置--通用--描述文件 ---添加信任 但是有时候 还是 会不能调试, 显示信息 是这样的 : ...