• 技术文章 >数据库 >Redis

    详解Redis数据结构之跳跃表

    藏色散人藏色散人2020-08-28 11:55:53转载654
    下面由Redis教程栏目给大家详解Redis数据结构之跳跃表,希望对需要的朋友有所帮助!

    前言

    跳跃表是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。这么说,我们可能很难理解,我们可以先回忆一下链表。

    一、复习跳跃表

    1.1 什么是跳跃表

    对于一个单链表来讲,即便链表中存储的数据是有序的,如果我们要想在其中查找某个数据,也只能从头到尾遍历链表。这样查找效率就会很低,时间复杂度会很高,是 O(n)。

    单链表

    如果我们想要提高其查找效率,可以考虑在链表上建索引的方式。每两个结点提取一个结点到上一级,我们把抽出来的那一级叫作索引。 一层跳跃表

    这个时候,我们假设要查找节点8,我们可以先在索引层遍历,当遍历到索引层中值为 7 的结点时,发现下一个节点是9,那么要查找的节点8肯定就在这两个节点之间。我们下降到链表层继续遍历就找到了8这个节点。原先我们在单链表中找到8这个节点要遍历8个节点,而现在有了一级索引后只需要遍历五个节点。

    从这个例子里,我们看出,加来一层索引之后,查找一个结点需要遍的结点个数减少了,也就是说查找效率提高了,同理再加一级索引。

    二层跳跃表

    从图中我们可以看出,查找效率又有提升。在例子中我们的数据很少,当有大量的数据时,我们可以增加多级索引,其查找效率可以得到明显提升。

    跳跃表

    像这种链表加多级索引的结构,就是跳跃表!

    二、Redis跳跃表

    Redis使用跳跃表作为有序集合键的底层实现之一,如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员是比较长的字符串时, Redis就会使用跳跃表来作为有序集合健的底层实现。

    这里我们需要思考一个问题——为什么元素数量比较多或者成员是比较长的字符串的时候Redis要使用跳跃表来实现?

    从上面我们可以知道,跳跃表在链表的基础上增加了多级索引以提升查找的效率,但其是一个空间换时间的方案,必然会带来一个问题——索引是占内存的。原始链表中存储的有可能是很大的对象,而索引结点只需要存储关键值值和几个指针,并不需要存储对象,因此当节点本身比较大或者元素数量比较多的时候,其优势必然会被放大,而缺点则可以忽略。

    2.1 Redis中跳跃表的实现

    Redis的跳跃表由zskiplistNode和skiplist两个结构定义,其中 zskiplistNode结构用于表示跳跃表节点,而 zskiplist结构则用于保存跳跃表节点的相关信息,比如节点的数量,以及指向表头节点和表尾节点的指针等等。

    Redis跳跃表

    上图展示了一个跳跃表示例,其中最左边的是 skiplist结构,该结构包含以下属性。

    zskiplistNode

    2.2 Redis跳跃表常用操作的时间复杂度

    操作时间复杂度
    创建一个跳跃表O(1)
    释放给定跳跃表以及其中包含的节点O(N)
    添加给定成员和分值的新节点平均O(logN),最坏O(logN)(N为跳跃表的长度)
    删除除跳跃表中包含给定成员和分值的节点平均O(logN),最坏O(logN)(N为跳跃表的长度)
    返回给定成员和分值的节点再表中的排位平均O(logN),最坏O(logN)(N为跳跃表的长度)
    返回在给定排位上的节点平均O(logN),最坏O(logN)(N为跳跃表的长度)
    给定一个分值范围,返回跳跃表中第一个符合这个范围的节点O(1)
    给定一个分值范围,返回跳跃表中最后一个符合这个范围的节点平均O(logN),最坏O(logN)(N为跳跃表的长度)
    给定一个分值范围,除跳跃表中所有在这个范围之内的节点平均O(logN),最坏O(logN)(N为跳跃表的长度)
    给定一个排位范围,鼎除跳跃表中所有在这个范围之内的节点O(N),N为被除节点数量
    给定一个分值范固(range),比如0到15,20到28,诸如此类,如果跳氏表中有至少一个节点的分值在这个范間之内,那么返回1,否则返回0O(N),N为被除节点数量

    本文重点

    小结

    跳跃表可能对我们来说是一种的稍陌生的数据结构。本篇文章简单介绍了跳跃表这种数据结构,并且分析了Redis中跳跃表的使用。下篇文章将继续分享Redis中用到的数据结构整数集合。敬请关注!

    以上就是详解Redis数据结构之跳跃表的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:cnblogs,如有侵犯,请联系admin@php.cn删除
    专题推荐:Redis
    上一篇:详解Redis的LRU算法 下一篇:一文搞定Redis五大数据类型及应用场景
    大前端线上培训班

    相关文章推荐

    • redis之List操作详解• 分享一个Vue+Laravel+Laravel-echo-server+redis的开源个人/多人博客• 详解Redis和队列• 详解Redis的LRU算法

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网