跳跃表原理和实现

跳跃表原理和实现

前提

有时候会被问到链表如果做到二分搜索,可能会有部分的人会去把链表中的值保存到数组来进行二分,但是如果知道跳跃表的话,那么这个数据结构就可以解决这个困惑,它允许快速查询一个有序连续元素的数据链表,它的效率可以做到和二分相同,都是O(logn)的平均时间复杂度,其空间复杂度为O(n)。

跳跃列表是在很多应用中有可能替代平衡树而作为实现方法的一种数据结构。跳跃列表的算法有同平衡树一样的渐进的预期时间边界,并且更简单、更快速和使用更少的空间。----by 发明者像是redis中有序集合就使用到了跳跃表。

原理

性质

首先,应该要了解跳跃表的性质;

  1. 由很多层结构组成;
  2. 每一层都是一个有序的链表,排列顺序为由高层到底层,都至少包含两个链表节点,分别是前面的head节点和后面的nil节点;
  3. 最底层的链表包含了所有的元素;
  4. 如果一个元素出现在某一层的链表中,那么在该层之下的链表也全都会出现(上一层的元素是当前层的元素的子集);
  5. 链表中的每个节点都包含两个指针,一个指向同一层的下一个链表节点,另一个指向下一层的同一个链表节点;

可以看到,这里一共有4层,最上面就是最高层(Level 3),最下面的层就是最底层(Level 0),然后每一列中的链表节点中的值都是相同的,用指针来连接着。跳跃表的层数跟结构中最高节点的高度相同。理想情况下,跳跃表结构中第一层中存在所有的节点,第二层只有一半的节点,而且是均匀间隔,第三层则存在1/4的节点,并且是均匀间隔的,以此类推,这样理想的层数就是logN。

搜索

其基本原理就是从最高层的链表节点开始,如果比当前节点要大和比当前层的下一个节点要小,那么则往下找,也就是和当前层的下一层的节点的下一个节点进行比较,以此类推,一直找到最底层的最后一个节点,如果找到则返回,反之则返回空。

代码实现大致为:

find(x)
{
    p = top;
    while (1) {
        while (p->next->key < x)
            p = p->next;
        if (p->down == NULL)
            return p->next;
        p = p->down;
    }
}

插入

既然要插入,首先需要确定插入的层数,这里有不一样的方法。1. 看到一些博客写的是抛硬币,只要是正面就累加,直到遇见反面才停止,最后记录正面的次数并将其作为要添加新元素的层;2. 还有就是一些博客里面写的统计概率,先给定一个概率p,产生一个0到1之间的随机数,如果这个随机数小于p,则将高度加1,直到产生的随机数大于概率p才停止,根据给出的结论,当概率为1/2或者是1/4的时候,整体的性能会比较好(其实当p为1/2的时候,也就是抛硬币的方法)。

当确定好要插入的层数以后,则需要将元素都插入到从最底层到第k层。

删除

在各个层中找到包含指定值的节点,然后将节点从链表中删除即可,如果删除以后只剩下头尾两个节点,则删除这一层。

原文地址:https://www.cnblogs.com/sunsky303/p/9214246.html

时间: 2024-10-11 14:16:48

跳跃表原理和实现的相关文章

浅析SkipList跳跃表原理及代码实现

本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈“跳跃表”的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢. 跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类的AVL树,红黑树等要低得多,这使得其

【转】浅析SkipList跳跃表原理及代码实现

SkipList在Leveldb以及lucence中都广为使用,是比较高效的数据结构.由于它的代码以及原理实现的简单性,更为人们所接受.首先看看SkipList的定义,为什么叫跳跃表? "Skip lists  are data structures  that use probabilistic  balancing rather  than  strictly  enforced balancing. As a result, the algorithms  for insertion  a

跳跃表原理

最近看了一种数据结构叫做skipList,redis和levelDB都是用了它.Skip List是在有序链表的基础上进行了扩展,解决了有序链表结构查找特定值困难的问题,查找特定值的时间复杂度为O(logn),他是一种可以代替平衡树的数据结构. 下面是skipList的一个介绍,转载来的,源地址:http://kenby.iteye.com/blog/1187303,为防止源地址丢失,故拷贝一份放在这里,望作者原谅. ———————————————转载开始————————————————— 为什

SkipList (跳跃表)解析及其实现

目录 导言 查找结点的效率如何提升? 什么是跳跃表? 跳跃表必须是完美的? 预备知识 抛硬币实验 模拟建表 操作解析 伪代码 代码实现 柔性数组 跳跃表的创建与销毁 跳跃表表头结构体定义 跳跃表结点结构体定义 建立跳跃表表头操作 操作解析 伪代码 代码实现 创建单个结点操作 操作解析 代码实现 销毁操作 操作解析 代码实现 插入操作 操作解析 时间复杂度 伪代码 代码实现 删除操作 操作解析 时间复杂度 伪代码 代码实现 查找操作 操作解析 伪代码 代码实现 时间复杂度分析 简单应用 跳跃字母表

跳跃表,字典树(单词查找树,Trie树),后缀树,KMP算法,AC 自动机相关算法原理详细汇总

第一部分:跳跃表 本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈"跳跃表"的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢. 跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类

跳跃表Skip List【附java实现】

skip list的原理 Java中的LinkedList是一种常见的链表结构,这种结构支持O(1)的随机插入及随机删除, 但它的查找复杂度比较糟糕,为O(n). 假如我们有一个有序链表如下,如果我们想找到值为59的节点,需要查找7次.怎么提高查询效率呢?通常的做法是使用二分法,但LinkedList的随机访问时间复杂度同样为O(n),因此朴素的二分法并不适用.那怎么办呢? 我们可以在节点中增加额外的跳跃节点,如下: 这样我们可以根据跳跃节点查询,只需要查找3次.至于查询47,我们先根据跳跃节点

查找——图文翔解SkipList(跳跃表)

跳跃表 跳跃列表(也称跳表)是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(logn)平均时间). 基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表元素,因此得名.所有操作都以对数随机化的时间进行. 如下图所示,是一个即为简单的跳跃表.传统意义的单链表是一个线性结构,向有序的链表中插入一个节点需要O(n)的时间,查找操作需要O(n)的时间.如果我们使用图中所示的跳跃表,就可以大大减少减少

跳跃表的分析与实现

----<大规模分布式存储系统:原理解析与架构实战>读书笔记 在了解了 Bitcask存储模型后,又开始研究LSM树存储引擎.LSM在实现的过程中使用了一个很有意思的数据结构:跳跃表.之前在<算法导论公开课>中听过这一节.当时感觉这种结构和二叉树简直是殊途同归,但是一直没有亲自动手实现过.这次又遇到了,就来实现试试看.话说跳跃表和各种平衡树一样,都是用来加速查询的.要随手实现一个B树不容易,但是实现一个跳跃表就简单很多. 跳跃表的简单介绍 跳跃列表一个有序链表,按层建造的.底层是一

第一部分 数据结构与对象 跳跃表

下面是跳跃表的基本原理,REDIS的实现大致相同 跳跃表的一个特点是,插入NODE是通过随机的方式来决定level的,比较奇特 下面是skipList的一个介绍,转载来的,源地址:http://kenby.iteye.com/blog/1187303,为防止源地址丢失,故拷贝一份放在这里,望作者原谅. ---------------转载开始----------------- 为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等. 想象一下,给