5.跳跃表

跳跃表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。

跳跃表支持平均O(logN),最坏O(N)复杂度的节点查找,还可以通过顺序性操作来批量处理节点。

Redis只有两个地方用到了跳跃表,一个是实现有序集合键,一个是在集群节点中用作内部数据结构。

5.1 跳跃表的实现


5.跳跃表_第1张图片

跳跃表由zskiplistNode和zskiplist两个结构定义

zskiplistNode用于表示跳跃表节点,zskiplist用于保存跳跃表节点的相关信息

zskiplist结构包含的属性:

header:指向跳跃表的表头节点

tail:指向跳跃表的表尾节点

level:记录目前条跳跃表内,层数最大的那个节点的层数(表头节点的层数不计算在内)

length:记录跳跃表的长度,也即是,跳跃表目前包含节点的数量

zskiplistNode结构包含的属性:

层:用L1、L2等标记节点的各个层。每个层都带有两个属性:前进指针和跨度。前进指针指向表尾方向的其他节点,跨度记录了前进指针所指向节点和当前节点的距离。

后退指针:节点中用BW标记节点的后退指针。它指向位于当前节点的前一个节点。用于从表尾向头遍历时使用。

分值:节点按各自所保存的分值从小到大排列

对象:节点所保存的成员对象

5.1.1 跳跃表节点


5.跳跃表_第2张图片
zskiplist结构定义

1.层:跳跃表节点的level 数组可以包含多个元素,每个元素都包含一个指向其他节点的指针,程序可以通过这些指针来加快访问其他节点的速度,层的数量越多,访问其他节点的速度就越快

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

3.跨度:层的跨度用来记录两个节点间的距离:

两个节点之间的跨度越大,它们相距的距离就越远

指向NULL的所有前进指针的跨度都为0,因为它们没有连向任何节点

4.后退指针:每个节点只有一个后退指针,所以每次只能后退至前一个节点。

5.分值和成员:节点的分值是以恶搞double类型的浮点数。节点的对象成员是一个指针,指向一个字符串对象,而字符串对象则保存着一个SDS值。

在同一个跳跃表中,各个节点保存的成员对象必须是唯一的,但是多个节点保存的分值却可以相同的:分值相同的节点将按照成员对象在字典序中的大小来进行排序,成员对象较小的节点会排在前面,而成员对象较大的节点会排在后面。

5.1.2 跳跃表


5.跳跃表_第3张图片
zskiplist结构定义

header和tail指针分贝指向跳跃表的表头和表尾节点,通过这两个指针,程序定位表头节点和表尾节点的复杂度为O(1)

通过使用length属性来记录节点的数量,程序O(1)的复杂度内返回跳跃表的长度。

level属性可以在O(1)的复杂度内获取跳跃表中层高最大的那个节点的层数量。

你可能感兴趣的:(5.跳跃表)