一、跳表简述

跳表可以看做是一个带有索引的链表,在介绍跳表之前先看一下一个普通的链表,假如当前维护了一个有序的链表:

现在要在这个链表中查找128,因为事先不知道链表中数值的分布情况,我们只能从前到后依次遍历,那么有没有什么取巧的方法呢?

如果我们能够存储下最中间节点的引用,比如存储节点29的引用,然后每次要查找节点的时候就先跟29比较一下,如果比29小就还是从前往后找(因为不会超过中间节点,从前往后和从中间往前区别不大),如果比29大就直接跳到29开始往后找,这种思想就是为链表添加了一个简单的索引,一下可以节省掉一半的查找时间。跳表的设计思想类似,通过为链表的每个节点设置高度来添加索引,不同的高度称为不同的层,每一层的next只能指向当前层的下一个节点,下面是一个跳表的示例:

最左面一列null为head节点,用于保存每一层的第一个节点,在查找的时候先从最高层开始查找,比如要在上面的跳表中查找128:

首先取最高层第六层的next,是47,比128小,直接跳到47,然后47的第六层的next是null,说明到了最后一个了,层数减少,47的第五层的next是255,比128大,也不行,继续减少层数,47的第四层的next是255,依然比128大,继续减少层数,47的第三层的next是128,get it!

看上面的过程有没有意识到一个问题,就是如果跳表的层数过多的话”比较-降层“这个过程就会有不少的浪费,比如上面的在47这个节点进行了4次比较才找到了有效的next节点,如果这个值再大一点的话就会退化得很严重。那么这个层是如何来的呢,跳表的高度是通过一个随机数决定的,初始时默认为一层,然后一直产生随机数只要小于0.5就将层数加一层继续随机,但是随机这种东西毕竟是不可控的,为了避免出现过高的层数最好还是设置一个最大层数以免某些节点的层数过大。

二、跳表的实现

跳表的简单Java实现:

SkipList.java:

package alg.link;import org.apache.commons.lang3.StringUtils;/*** 跳表结构的简单Java实现** @author CC11001100*/
public class SkipList<T extends Comparable<T>> {private static final double DEFAULT_CONTINUE_INCREMENT_LEVEL_THRESHOLD = 0.75;private static final int DEFAULT_MAX_LEVEL = 10;// 用于控制层数,决定层数时当随机数小于此值时会一直升层直到最大,取值范围[0, 1],值越大越可能得到高层数,此值设置不当很有可能退化成链表private double continueIncrementLevelThreshold;// 为了防止随机数出现异常情况过高,对最大层数做一个限制private int maxLevel;// 链表的头结点,每一层的头都保存在这里private Node<T> head;public SkipList() {this(DEFAULT_CONTINUE_INCREMENT_LEVEL_THRESHOLD, DEFAULT_MAX_LEVEL);}public SkipList(double threshold) {this(threshold, DEFAULT_MAX_LEVEL);}public SkipList(double threshold, int maxLevel) {this.continueIncrementLevelThreshold = threshold;this.maxLevel = maxLevel;this.head = new Node<>(null, 0);// 初始化时就将其扩充到最大避免后面扩容增加复杂性,只有head会浪费一些空间其它节点都是有几层申请多长的数组this.head.next = new Node[maxLevel];}public void add(T value) {Node[] previous = findPrevious(value);Node<T> node = new Node<>(value, randomLevel());for (int i = 0; i < previous.length && i < node.level; i++) {node.next[i] = previous[i].next[i];previous[i].next[i] = node;}if (node.level > head.level) {for (int i = node.level - 1; i >= 0 && head.next[i] == null; i--) {head.next[i] = node;}head.level = node.level;}}public void remove(T value) {Node[] previous = findPrevious(value);Node node = previous[0].next[0];if (node.value.compareTo(value) != 0) {return;}for (int i = 0; i < previous.length && i < node.level; i++) {previous[i].next[i] = node.next[i];}}public boolean contains(T value) {Node[] previous = findPrevious(value);Node node = previous[0].next[0];return node.value.compareTo(value) == 0;}private int randomLevel() {int level = 1;while (level < maxLevel && Math.random() < continueIncrementLevelThreshold) {level++;}return level;}private Node[] findPrevious(T value) {Node[] previous = new Node[head.level];Node<T> node = head;for (int i = head.level - 1; i >= 0; i--) {while (node.next[i] != null && node.next[i].value.compareTo(value) < 0) {node = node.next[i];}previous[i] = node;}return previous;}/*** head_next   level_next                         # 注释,实际不会打印标题* 67                      67* 67                      67* 67                      67* 67                      67* 19              19      67* 19              19      67* 6           6   19      67* 6           6   19      67  82* 6           6   19  46  67  82*/public void show() {StringBuilder sb = new StringBuilder();for (int i = maxLevel; i > 0; i--) {// 这一层级的头指针指向谁Node levelHead = head.next[i - 1];if (levelHead != null) {sb.append(String.format("%-10s", levelHead.value.toString())).append("\t");} else {sb.append(StringUtils.repeat(" ", 10)).append("\t");}// 然后是每一层按层数是否出现打印value或空白填充Node node = head.next[0];while (node != null) {String s = node.value.toString();if (node.level >= i) {sb.append(s).append("\t");} else {sb.append(StringUtils.repeat(" ", s.length())).append("\t");}node = node.next[0];}if (i != 1) {sb.append("\n");}}System.out.println(sb.toString());}private static class Node<T extends Comparable<T>> {// 当前节点的值T value;// 当前节点的层数int level;// 记录当前节点在每一层的next节点Node<T>[] next;private Node(T value, int level) {this.value = value;this.level = level;this.next = new Node[level];}}}

SkipListTest.java:

package alg.link;import java.util.ArrayList;
import java.util.List;
import java.util.Random;/*** @author CC11001100*/
public class SkipListTest {public static void main(String[] args) {SkipList<Integer> skipList = new SkipList<>();Random random = new Random();List<Integer> numList = new ArrayList<>();for (int i = 0; i < 30; i++) {int n = random.nextInt(100);System.out.println("now insert " + n);skipList.add(n);skipList.show();numList.add(n);System.out.println("---------------------------------------------------------------------------");if (Math.random() < 0.5 && !numList.isEmpty()) {int removeNum = numList.remove(random.nextInt(numList.size()));System.out.println("now remove " + removeNum);skipList.remove(removeNum);skipList.show();System.out.println("---------------------------------------------------------------------------");}}}}

测试效果:

now insert 3535            35
35          35
35          35
---------------------------------------------------------------------------
now insert 56
56              56
56              56
56              56
56              56
56              56
56              56
56              56
35          35  56
35          35  56
35          35  56
---------------------------------------------------------------------------
now remove 35
56          56
56          56
56          56
56          56
56          56
56          56
56          56
56          56
56          56
56          56
---------------------------------------------------------------------------
now insert 45
56              56
56              56
56              56
56              56
56              56
45          45  56
45          45  56
45          45  56
45          45  56
45          45  56
---------------------------------------------------------------------------
now remove 5645         45
45          45
45          45
45          45
45          45
---------------------------------------------------------------------------
now insert 745              45
45              45
45              45
45              45
7           7   45
---------------------------------------------------------------------------
now insert 5745             45
45              45
45              45
45              45  57
7           7   45  57
---------------------------------------------------------------------------
now remove 745          45
45          45
45          45
45          45  57
45          45  57
---------------------------------------------------------------------------
now insert 7545         45
45          45
45          45
45          45  57
45          45  57  75
---------------------------------------------------------------------------
now remove 7545         45
45          45
45          45
45          45  57
45          45  57
---------------------------------------------------------------------------
now insert 9645         45
45          45      96
45          45      96
45          45  57  96
45          45  57  96
---------------------------------------------------------------------------
now remove 9645         45
45          45
45          45
45          45  57
45          45  57
---------------------------------------------------------------------------
now insert 40
40          40
40          40
40          40
40          40
40          40
40          40  45
40          40  45
40          40  45
40          40  45  57
40          40  45  57
---------------------------------------------------------------------------
now remove 4045         45
45          45
45          45
45          45  57
45          45  57
---------------------------------------------------------------------------
now insert 6945         45
45          45
45          45      69
45          45  57  69
45          45  57  69
---------------------------------------------------------------------------
now insert 1145             45
11          11  45
11          11  45      69
11          11  45  57  69
11          11  45  57  69
---------------------------------------------------------------------------
now insert 1945                 45
11          11      45
11          11      45      69
11          11  19  45  57  69
11          11  19  45  57  69
---------------------------------------------------------------------------
now insert 5545                 45
11          11      45
11          11      45  55      69
11          11  19  45  55  57  69
11          11  19  45  55  57  69
---------------------------------------------------------------------------
now remove 5545                 45
11          11      45
11          11      45      69
11          11  19  45  57  69
11          11  19  45  57  69
---------------------------------------------------------------------------
now insert 4345                     45
11          11          45
11          11          45      69
11          11  19      45  57  69
11          11  19  43  45  57  69
---------------------------------------------------------------------------
now remove 4345                 45
11          11      45
11          11      45      69
11          11  19  45  57  69
11          11  19  45  57  69
---------------------------------------------------------------------------
now insert 545                      45
11              11      45
11              11      45      69
11              11  19  45  57  69
5           5   11  19  45  57  69
---------------------------------------------------------------------------
now remove 545                  45
11          11      45
11          11      45      69
11          11  19  45  57  69
11          11  19  45  57  69
---------------------------------------------------------------------------
now insert 9245                 45
11          11      45
11          11      45      69
11          11  19  45  57  69  92
11          11  19  45  57  69  92
---------------------------------------------------------------------------
now remove 4511         11
11          11          69
11          11  19  57  69  92
11          11  19  57  69  92
---------------------------------------------------------------------------
now insert 5611         11
11          11              69
11          11  19      57  69  92
11          11  19  56  57  69  92
---------------------------------------------------------------------------
now insert 3111         11
11          11                  69
11          11  19  31      57  69  92
11          11  19  31  56  57  69  92
---------------------------------------------------------------------------
now insert 2911         11
11          11      29              69
11          11  19  29  31      57  69  92
11          11  19  29  31  56  57  69  92
---------------------------------------------------------------------------
now insert 9611         11                              96
11          11      29              69      96
11          11  19  29  31      57  69  92  96
11          11  19  29  31  56  57  69  92  96
---------------------------------------------------------------------------
now insert 011              11                              96
0           0   11      29              69      96
0           0   11  19  29  31      57  69  92  96
0           0   11  19  29  31  56  57  69  92  96
---------------------------------------------------------------------------
now remove 1911             11                          96
0           0   11  29              69      96
0           0   11  29  31      57  69  92  96
0           0   11  29  31  56  57  69  92  96
---------------------------------------------------------------------------
now insert 5411             11          54                  96
0           0   11  29      54          69      96
0           0   11  29  31  54      57  69  92  96
0           0   11  29  31  54  56  57  69  92  96
---------------------------------------------------------------------------
now insert 811                  11          54                  96
0           0       11  29      54          69      96
0           0       11  29  31  54      57  69  92  96
0           0   8   11  29  31  54  56  57  69  92  96
---------------------------------------------------------------------------
now remove 5611                 11          54              96
0           0       11  29      54      69      96
0           0       11  29  31  54  57  69  92  96
0           0   8   11  29  31  54  57  69  92  96
---------------------------------------------------------------------------
now insert 6011                 11          54                  96
0           0       11  29      54          69      96
0           0       11  29  31  54  57      69  92  96
0           0   8   11  29  31  54  57  60  69  92  96
---------------------------------------------------------------------------
now insert 4141                             41
11                  11          41  54                  96
0           0       11  29      41  54          69      96
0           0       11  29  31  41  54  57      69  92  96
0           0   8   11  29  31  41  54  57  60  69  92  96
---------------------------------------------------------------------------
now remove 9241                             41
11                  11          41  54              96
0           0       11  29      41  54          69  96
0           0       11  29  31  41  54  57      69  96
0           0   8   11  29  31  41  54  57  60  69  96
---------------------------------------------------------------------------
now insert 2041                                 41
11                  11  20          41  54              96
0           0       11  20  29      41  54          69  96
0           0       11  20  29  31  41  54  57      69  96
0           0   8   11  20  29  31  41  54  57  60  69  96
---------------------------------------------------------------------------
now remove 4111                 11  20          54              96
0           0       11  20  29      54          69  96
0           0       11  20  29  31  54  57      69  96
0           0   8   11  20  29  31  54  57  60  69  96
---------------------------------------------------------------------------
now insert 5811                 11  20          54                  96
0           0       11  20  29      54      58      69  96
0           0       11  20  29  31  54  57  58      69  96
0           0   8   11  20  29  31  54  57  58  60  69  96
---------------------------------------------------------------------------
now remove 3111                 11  20      54                  96
0           0       11  20  29  54      58      69  96
0           0       11  20  29  54  57  58      69  96
0           0   8   11  20  29  54  57  58  60  69  96
---------------------------------------------------------------------------
now insert 7911                 11  20      54                      96
0           0       11  20  29  54      58      69      96
0           0       11  20  29  54  57  58      69  79  96
0           0   8   11  20  29  54  57  58  60  69  79  96
---------------------------------------------------------------------------
now insert 3811                 11  20          54                      96
0           0       11  20  29      54      58      69      96
0           0       11  20  29  38  54  57  58      69  79  96
0           0   8   11  20  29  38  54  57  58  60  69  79  96
---------------------------------------------------------------------------
now insert 3111                 11  20              54                      96
0           0       11  20  29          54      58      69      96
0           0       11  20  29  31  38  54  57  58      69  79  96
0           0   8   11  20  29  31  38  54  57  58  60  69  79  96
---------------------------------------------------------------------------
now remove 7911                 11  20              54                  96
0           0       11  20  29          54      58      69  96
0           0       11  20  29  31  38  54  57  58      69  96
0           0   8   11  20  29  31  38  54  57  58  60  69  96
---------------------------------------------------------------------------
now insert 7811                 11  20              54                  78  96
0           0       11  20  29          54      58      69  78  96
0           0       11  20  29  31  38  54  57  58      69  78  96
0           0   8   11  20  29  31  38  54  57  58  60  69  78  96
---------------------------------------------------------------------------
now remove 011              11  20              54                  78  96
11              11  20  29          54      58      69  78  96
11              11  20  29  31  38  54  57  58      69  78  96
8           8   11  20  29  31  38  54  57  58  60  69  78  96
---------------------------------------------------------------------------

.

转载于:https://www.cnblogs.com/cc11001100/p/9801252.html

数据结构笔记之跳表(SkipList)相关推荐

  1. java数据结构红黑树上旋下旋_存储系统的基本数据结构之一: 跳表 (SkipList)

    在接下来的系列文章中,我们将介绍一系列应用于存储以及IO子系统的数据结构.这些数据结构相互关联又有着巨大的区别,希望我们能够不辱使命的将他们分门别类的介绍清楚.本文为第一节,介绍一个简单而又有用的数据 ...

  2. 每日一博 - 如何理解跳表(SkipList)

    文章目录 什么是跳跃表SkipList 跳表关键字 Why Skip List Code 跳表-查询 跳表-删除 跳表-插入 小结 完整Code 什么是跳跃表SkipList 跳跃表(简称跳表)由美国 ...

  3. 跳表-skiplist的简单实现

    文章目录 1.什么是跳表-skiplist 2.skiplist的效率如何保证? 3.skiplist的实现 4.skiplist跟平衡搜索树和哈希表的对比 1.什么是跳表-skiplist skip ...

  4. 为啥 redis 使用 跳表 (skiplist) 而不是使用 red-black?

    基本结论 1.实现简单. 2.区间查找快.跳表可以做到O(logn) 的时间复杂度定位区间的起点,然后在原始链表中顺序往后遍历就可以了. 3.并发环境优势.红黑树在插入和删除的时候可能需要做一些reb ...

  5. 什么是跳表 skiplist ?

    什么是跳表 skiplist ? 文章目录 什么是跳表 skiplist ? 特性 实现 结构 查找 插入 删除 完整代码 参考 跳表可以快速地查找.插入.删除.据说可以替代红黑树.Redis中的有序 ...

  6. 一种数据结构 跳表skiplist

    跳表是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的. 下载地址 : http://download ...

  7. Redis数据结构之——跳表skiplist

    写在前面 以下内容是基于Redis 6.2.6 版本整理总结 一.跳表(skiplist) 如何理解跳表?在了解跳表之前,我们先从普通链表开始,一点点揭开跳表的神秘面纱~ 首先,普通单链表来说,即使链 ...

  8. 数据结构--跳表SkipList

    对单链表查找一个元素的时间复杂度是 O(n) 通过对链表建立多级索引的结构,就是跳表,查找任意数据.插入数据.删除数据的时间复杂度均为 O(log n) 前提:建立了索引,用空间换时间的思路 (每两个 ...

  9. 数据结构之跳表Skiplist

    一.问题引入 二.何为跳表 跳表具有如下性质: 1. 跳表由很多层结构组成: 2.跳表中每一层都是一个有序链表: 3.跳表的最底层(Level 1)的链表包含所有元素: 4.如果一个元素出现在跳表 L ...

最新文章

  1. 中欧谋定原产地保护-农业大健康·万祥军:战略格局地理标志
  2. Mysql日志-RedoLog、UndoLog和BinLog的关系捋顺
  3. codeforces 935E Fafa and Ancient Mathematics 语法树、动态规划
  4. 使用iBatis数据映射框架吧
  5. 15款非常有用的前端开发CSS网格(grid system)生成器
  6. 小D课堂 - 新版本微服务springcloud+Docker教程_5-02 Netflix开源组件断路器
  7. 版本设置X:none node Title golang版本错误
  8. linux中dpkg找不到命令_Linux中tree命令的使用
  9. 基于php的学校固定资产管理系统
  10. Java中什么是句柄
  11. windows系统下,在iis管理器(无W3SVC/WAS服务)或网站IIS功能不全(无默认文档、模块、各种规则设置等)
  12. Java冒泡排序法 经典例题
  13. Django 2.1文档
  14. 天狗农业技术网采用的跨平台的Amaze UI设计
  15. 【coq】函数语言设计 笔记 03 - list
  16. 有个程序媛上司是什么体验
  17. 关于AWS亚马逊云计算平台EC2如何删除快照
  18. freesurfer recon-all并行运算parallel
  19. 好看的充电宝有哪些?好看的充电宝推荐
  20. 安卓模拟器刷小米系统_小米安卓模拟器|小米手游模拟器下载 v1.0.0.8 电脑版_小皮网...

热门文章

  1. linux shell 删除key \xAC\xED\x00\x05t\x00\x04${key} 序列化16进制
  2. 母亲节快乐flash动画素材
  3. 基于SMS短信平台给手机发送短信
  4. 模拟浏览器整理电影榜单
  5. Ubuntu 快速显示桌面快捷键
  6. 任何物体都在以光速运动,你能理解这一认识吗?
  7. python中特殊文件和特殊函数
  8. 通达信经典实用选股公式
  9. 网络基础-路由器DHCP配置
  10. CVPR2021 行人重识别/Person Re-identification 论文+开源代码汇总