《Redis设计与实现》第五章总结:跳跃表

本文详细介绍了Redis中跳表的底层实现原理,包括跳表节点和跳表的结构定义,以及跳表在有序集合和集群节点中的应用。解析了跳表节点的层、前进指针、跨度、后退指针、分值和成员对象等属性,同时阐述了跳表的快速访问特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.跳跃表

有序集合键的底层实现之一:如果一个有序集合包含的元素数量比较多,或者有序集合中元素是比较长的字符串时,就使用跳表
在集群节点中用作内部数据结构
跳表在Redis中只有这两个用途

4.1 跳表总览

redis.h/zskiplistNode和redis.h/zskiplist两个结构定义,zskiplistNode表示跳表节点,zskiplist用于保存跳表节点的相关信息,如节点数量,头尾指针等

例子:
在这里插入图片描述
如上图,最左边的是zskiplist结构,其属性解释如下:
在这里插入图片描述
而右边的四个为zskiplistNode结构,其属性解释如下:
在这里插入图片描述
下面看看跳表节点和跳表的具体解析

4.2 跳表节点实现

redis.h/zskiplistNode:
在这里插入图片描述
下面逐个分析其属性

4.2.1 层:

每次创建一个新节点时,程序根据幂次定律(越大的数出现的概率越小)随机生成一个介于1到32之间的值作为level数组(level[])的大小,也就是层的高度

例子:
在这里插入图片描述

4.2.1.1 前进指针

每一层都有一个指向表尾方向的前进指针,用于从表头向表尾方向访问节点

例子:虚线表示出了从表头向表尾方向,遍历跳表中所有节点的路径
在这里插入图片描述

4.2.1.2 跨度

每一层的跨度,用于记录两个节点之间的距离

作用:不是用来遍历操作的,因为遍历操作只使用前进指针即可;实际上是用来计算排位的:在查找某个节点的过程中,将沿途访问过的所有层的跨度累计起来,得到的结果就是目标节点在跳表中的排位

例子:虚线标记了在跳表中查找分值为3.0、成员对象为o3的节点时,沿途经历的层;可以看出,查找过程只经过了一个层,且跨度为3,所以此节点排位为3
在这里插入图片描述

4.2.2 后退(BW)指针

用于从表尾向表头方向访问节点

与前进指针区别:前进指针一次可以跳过多个节点,因为每个节点都多个层,每层都有一个前进指针,所以不必限制;后退指针每次只能后退至前一个节点,因为每个节点只有一个后退指针

例子:从表尾向表头遍历,首先通过tail定位到表尾,再通过后退指针遍历即可
在这里插入图片描述

4.2.3 分值和成员对象

成员对象必须唯一,分值则可以重复;分值相同的节点将按照成员对象在字典序中的大小来进行排序,小的靠前

4.3 跳表实现

redis.h/zskiplist:
在这里插入图片描述
虽然仅靠多个跳跃表节点即可组成一个跳表,但是类似链表,使用一个zskiplist结果来持有这些节点,程序可以更方便地对整个跳表进行处理,如快速访问表头和表尾(O(1))、快速获取跳表节点的数量(length属性,O(1))、快速获取层数最高的节点(level,O(1),注意不包括表头)等信息

例子:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值