跳跃表简介

跳跃表(skiplist)是一个有序的数据结构,它通过在每个节点维护不同层次指向后续节点的指针,以达到快速访问指定节点的目的。跳跃表在查找指定节点时,平均时间复杂度为,最坏时间复杂度为O(N)。

Redis使用跳跃表(skiplist)作为有序集合(zset)的底层实现之一。当有序集合的元素个数大于等于zset-max-ziplist-entries(默认为128个),或者每个元素成员的长度大于等于zset-max-ziplist-value(默认为64字节)的时候,使用跳跃表和哈希表作为有序集合的内部实现。

举个例子,我们使用zadd命令创建一个以跳跃表为实现的有序集合:

127.0.0.1:6379> zadd one-more-zset 1 long-long-long-long-long-long-long-long-long-long-long-long-long-long
(integer) 1
127.0.0.1:6379> zrange one-more-zset 0 -1
1) "long-long-long-long-long-long-long-long-long-long-long-long-long-long"
127.0.0.1:6379> object encoding one-more-zset
"skiplist"

跳跃表的实现

在Redis中的跳跃表是由zskiplist结构表示的,zskiplist结构包含由多个跳跃表节点组成的双向链表,每一个跳跃表节点都保存着元素成员和对应的分钟。下面我们一个一个地详细了解一下。

zskiplist结构

跳跃表是由zskiplist结构表示的,它包含以下几个属性:

  • header属性: 指向头部跳跃表节点的指针。
  • tail属性:指向尾部跳跃表节点的指针。
  • level属性:表示跳跃表中层数最大的节点的层数,表头节点的层数不计算在内。
  • length属性:表示跳跃表中的节点总数。

跳跃表节点的结构

跳跃表节点使用zskiplistNode结构表示,它包含以下几个属性:

  • level属性:表示层的数组,数组中每个项使用zskiplistLevel结构表示,它包含以下两个属性:
    • forward属性:指向位于表尾方向其他节点的指针。
    • span属性:当前节点到forward指向的节点跨越了多少个节点。
  • backward属性:指向当前节点的前一个节点的指针。
  • obj属性:指向元素成员的指针。
  • score属性:当前元素成员对应的分数。

图解跳跃表

说了这么多,都比较抽象不容易理解,我们来举个例子:

这就是一个跳跃表的内部结构,其中有4个元素,键分别是:万、猫、学、社。

为什么不使用平衡树?

跳跃表以有序的方式在层次化的链表中保存元素, 在大多数情况下,跳跃表的效率可以和平衡树媲美,查找、删除、添加等操作都可以在对数期望时间下完成, 并且比起平衡树来说, 跳跃表的实现要简单直观得多。所以在Redis中没有使用平衡树,而是使用了跳跃表。

最后,谢谢你这么帅,还给我点赞关注

微信公众号:万猫学社

微信扫描二维码

关注后回复「电子书」

获取12本Java必读技术书籍

5分钟了解Redis的内部实现跳跃表(skiplist)的更多相关文章

  1. Redis实现之字典跳跃表

    跳跃表 跳跃表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.跳跃表支持平均O(logN).最坏O(N)的时间复杂度查找,还可以通过顺序性操作来批量处理节 ...

  2. Redis学习之zskiplist跳跃表源码分析

    跳跃表的定义 跳跃表是一种有序数据结构,它通过在每个结点中维持多个指向其他结点的指针,从而达到快速访问其他结点的目的 跳跃表的结构 关于跳跃表的学习请参考:https://www.jianshu.co ...

  3. Redis数据结构之跳跃表-skiplist

    在Redis中,zset是一个复合结构: 使用hash来存储value和score的映射关系 使用跳跃表来提供按照score进行排序的功能,同时可以指定score范围来获取value列表 结构 zse ...

  4. Redis 底层数据结构之跳跃表

    文章参考 <Redis 设计与实现>黄建宏 Redis(2) 跳跃表 跳跃表 跳跃表 skiplist 是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节 ...

  5. 图解Redis之数据结构篇——跳跃表

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

  6. redis 5.0.7 源码阅读——跳跃表skiplist

    redis中并没有专门给跳跃表两个文件.在5.0.7的版本中,结构体的声明与定义.接口的声明在server.h中,接口的定义在t_zset.c中,所有开头为zsl的函数. 一.数据结构 单个节点: t ...

  7. 4.redis设计与实现--跳跃表

    1.跳跃表由两个结构体构成: 2.总结:

  8. 5分钟了解Redis的内部实现快速列表(quicklist)

    快速列表简介 在Redis3 .2版本之前,存储列表(list)数据结构使用的是压缩列表(ziplist)和链表(linkedlist),当列表元素个数比较少并且每个元素占用空间比较小的时候,使用压缩 ...

  9. 数据结构与算法简记--redis有序集合实现-跳跃表

    跳表 定义 为一个值有序的链表建立多级索引,比如每2个节点提取一个节点到上一级,我们把抽出来的那一级叫做索引或索引层.如下图所示,其中down表示down指针,指向下一级节点.以此类推,对于节点数为n ...

随机推荐

  1. LinkedHashSet、Map、Map接口HashMap、Hashtable,TreeSet、TreeMap、如何选择使用集合实现类,Collections工具类

    一.Set接口实现类LinkedHashSet 实现继承图: 1.LinkedHashSet的全面说明 1) LinkedHashSet是 HashSet的子类 2) LinkedHashSet底层是 ...

  2. Node介绍

    https://segmentfault.com/a/1190000006121183 一. 概述 Node.js是基于Chrome JavaScript运行时建立的一个平台,实际上它是对Google ...

  3. Note -「线性规划」学习笔记

    \(\mathcal{Definition}\)   线性规划(Linear Programming, LP)形式上是对如下问题的描述: \[\operatorname{maximize}~~~~z= ...

  4. 用 Python 简单生成 WAV 波形声音文件

    Python 简单生成 WAV 波形声音文件 让机器发出声响,本身就是一件充满魔法的事情.有没有想过,用一段简单的代码,生成一个最简单的声音呢?Python 这门脚本语言的库十分丰富,借助于其中的三个 ...

  5. 『无为则无心』Python面向对象 — 52、私有成员方法(类中行为的封装)

    Python对于类的成员没有严格的访问控制限制,这与其他面向对象的编程语言是有所区别的. 关于私有方法其实和私有属性差不多,有如下要点: 1.通常我们约定,两个下划线开头的方法是私有方法. 2.类内部 ...

  6. Python中类的两种用法

    第一种用法是使用类生成实例对象.类作为实例对象的模版,每个实例创建后,都将拥有类的所有属性和方法. 第二种用法是用类将多个函数(方法)打包封装在一起,让类中的方法相互配合.

  7. .Net Core AOP之IResultFilter

    一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...

  8. tor-browse

    https://sourceforge.net/projects/t-browser/

  9. 软考高级及杭州E类人才申请经验分享

    目录 前沿 软考高项 什么是软考 软考的基本过程 报名 是否报班 高项考些什么以及需要哪些书 如何准备 杭州E类人才申请 如何申请 大概的流程 前沿 挺久没更新了,自从成为房奴后,看书的时间就变少了, ...

  10. 【C# 基础概念】C# 4 dynamic - var, object, dynamic的区别以及dynamic的使用

    阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 一. 为什么是它们三个? 拿这三者比较的原因是它们在使用的时候非常相似.你 ...