文章参考

《Redis 设计与实现》黄建宏

Redis(2) 跳跃表

跳跃表

跳跃表 skiplist 是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的,平均复杂度 O(logN)、最坏 O(N)

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

另一个使用跳表的事集群节点中用作内部数据结构。

  • header 指向跳跃表的表头节点
  • tail 指向跳跃表的表尾节点
  • level 记录目前跳跃表内,层数最大的那个节点的层数(表头节点不计算在内)
  • length 记录跳跃表的长度,也就是目前节点的数量

跳跃表节点 zskiplistNode

typedef struct zskiplistNode {
// 层
struct zskiplistLevel {
// 前进指针
struct zskiplistNode *forward;
unsigned int span;
} level[];
// 后退指针
struct zskiplistNode *backward;
// 分值
double score;
// 成员对象
robj *obj;
} zskiplistNode;
  1. 跳跃表节点的 level 数组可以包含多个元素, 每个元素都包含一个指向其他节点的指针

    每次创建一个新的跳跃表节点时候,随机生成 1~32 之间的值作为 level 数组的大小,即层的高度

  2. 前进指针

    每个层都有一个指向表尾方向的前进指针 forward,用于遍历到结尾

  3. 跨度

    span属性用于记录两个节点之间的距离:两个节点跨度越大,它们相距得越远,

  4. 后退指针

    后退指针用于从表尾向表头访问节点(和 forward 不同,每次只能后退一个节点)

  5. 分值和成员

    节点都按分值从小到大排序

    节点的成员对象 obj 指向一个 SDS 字符串

跳跃表

多个跳跃表节点可以组成一个跳跃表

typedef struct zskiplist {
// 表头和表尾节点
struct skiplistNode *header, *tail;
// 表中节点的数量
unsigned long length;
// 表中层数最大节点的层数
int level;
} zskiplist;

header 和 tail 指针能让定位 表头和表尾 复杂度为 O(1)

length 让程序可以在 O(1) 复杂度返回跳跃表长度。

跳跃表的查找过程

比如我们想要查找 7,查找的路径则是沿着下图中标注出红色指针所指的方向进行的(每次查找都是从最高的 level 开始):

跳跃表的创建过程

从上面的创建和插入的过程中可以看出,每一个节点的层数(level)是随机出来的,而且新插入一个节点并不会影响到其他节点的层数,因此,插入操作只需要修改节点前后的指针,而不需要对多个节点都进行调整,这就降低了插入操作的复杂度。

Redis 底层数据结构之跳跃表的更多相关文章

  1. Redis 的底层数据结构(跳跃表)

    字典相对于数组,链表来说,是一种较高层次的数据结构,像我们的汉语字典一样,可以通过拼音或偏旁唯一确定一个汉字,在程序里我们管每一个映射关系叫做一个键值对,很多个键值对放在一起就构成了我们的字典结构. ...

  2. redis 系列7 数据结构之跳跃表

    一.概述 跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树(关系型数据库的索引就是平衡树 ...

  3. Redis数据结构之跳跃表

    跳跃表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的. 一.跳跃表结构定义1. 跳跃表节点结构定义: 2. 跳跃表结构定义: 示例: 二.跳跃表节点中各种 ...

  4. Redis实现之字典跳跃表

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

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

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

  6. Redis 底层数据结构介绍

    Redis 底层数据结构 版本:2.9 支持的数据类型: 字符串 散列 列表 集合 有序集合 字符串 Redis 利用原生的 c 字符串进行了一次封装.封装的字符串叫做简单动态字符串:SDS(simp ...

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

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

  8. Redis底层数据结构详解

    上一篇说了Redis有五种数据类型,今天就来聊一下Redis底层的数据结构是什么样的.是这一周看了<redis设计与实现>一书,现来总结一下.(看书总是非常烦躁的!) Redis是由C语言 ...

  9. 平衡树:为什么Redis内部实现用跳跃表

    摘要:Redis使用跳跃表(skiplist)作为有序集合(zset)的底层实现之一. 本文分享自华为云社区<5分钟了解Redis的内部实现跳跃表(skiplist)>,作者:万猫学社. ...

随机推荐

  1. Ubuntu 20.04 配置多网卡链路聚合

    Ubuntu 20.04 配置多网卡链路聚合 多网卡IP配置 首先查看网卡信息 root@it:~# ip add 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65 ...

  2. property - 必应词典 美['prɑpərti]英['prɒpə(r)ti] n.属性;财产;财产权;【戏】道具

    英语 (已检测) 自动检测 阿拉伯语 自动检测 爱尔兰语 自动检测 爱沙尼亚语 自动检测 保加利亚语 自动检测 冰岛语 自动检测 波兰语 自动检测 波斯尼亚语(拉丁语) 自动检测 波斯语 自动检测 丹 ...

  3. ltp 测试流程及测试脚本分析

    LTP介绍 (2011-03-25 18:03:53) 转载▼ 标签: ltp linux 压力测试 杂谈 分类: linux测试 LTP介绍 一.LTP介绍1.简介LTP(Linux Test Pr ...

  4. Java lambda 表达式详解(JDK 8 新特性)

    什么是 lambda 表达式 lambda 表达式(拉姆达表达式)是 JAVA 8 中提供的一种新的特性,它使 Java 也能进行简单的"函数式编程". lambda 表达式的本质 ...

  5. Java反射机制 之 获取类的 方法 和 属性(包括构造函数)(Day_06)

    把自己立成帆,才能招来凤. 运行环境 JDK8 + IntelliJ IDEA 2018.3  本文中使用的jar包链接 https://files.cnblogs.com/files/papercy ...

  6. 【玩转PDF】贼稳,产品要做一个三方合同签署,我方了!

    一.前言 事情是这个样子的,小农的公司,之前有个功能需要签署来进行一系列的操作,于是我们引入了一个三方平台的签署--上上签,但是有一个比较尴尬的点就是,它不支持合同在浏览器上和附件一起预览的,我们想要 ...

  7. kotlin知识点

    主构造函数里的参数,如果不声明为var或者val,则这个参数一般是用来初始化父类.它不算是这个类的字段,它的作用域只在主构造函数当中. val 的对象不仅数据不能变, 引用也不能变. //自定义的类似 ...

  8. 使用 Flux+Flagger+Istio+Kubernetes 实战 GitOps 云原生渐进式(金丝雀)交付

    在这篇指南中,你将获得使用 Kubernetes 和 Istio 使用 GitOps 进行渐进式交付(Progressive Delivery)的实际经验. 介绍 gitops-istio GitOp ...

  9. 在Spring Bean实例过程中,如何使用反射和递归处理的Bean属性填充?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! <Spring 手撸专栏>目录 [x] 第 1 章:开篇介绍,我要带你撸 Spri ...

  10. 深度学习与TensorFlow

    深度学习与TensorFlow DNN(深度神经网络算法)现在是AI社区的流行词.最近,DNN 在许多数据科学竞赛/Kaggle 竞赛中获得了多次冠军. 自从 1962 年 Rosenblat 提出感 ...