跳跃表是一种有序的数据结构,它的平均时间复杂度是O(logN),它通过在一个节点中维护多个指向其他节点的指针,达到快速查找和访问其他节点的目的。在redis中跳跃表只用在实现sorted set和集群节点中。
下面来看看跳跃表的结构
typedef struct zskiplist {
/* 节点指针,分别指向头节点和尾节点 */
struct zskiplistNode *header, *tail;
/* 长度 */
unsigned long length;
/* 等级 */
int level;
} zskiplist;
其中节点的结构如下
typedef struct zskiplistNode {
/* sds类型的元素 */
sds ele;
/* 分数 */
double score;
/* 后退指针 */
struct zskiplistNode *backward;
/* 层级 */
struct zskiplistLevel {
/* 前进指针 */
struct zskiplistNode *forward;
/* 跨度 */
unsigned int span;
} level[];
} zskiplistNode;
结构图来自《redis设计与实现》一书
看图来说说结构中的属性:(从左到右我们把节点编号为1、2、3、4)
跳跃表结构:
header:指向头节点1
tail:指向尾节点4
level:除开表头节点,剩余所有的节点中层级数最大的那个节点的层级,也就是节点4的层级,=5
length:除开表头节点的剩余所有节点的个数,=3
节点结构:
ele:元素。图中的o1、o2、o3
score:分数。图中的1.0、2.0、3.0,用于计算节点在跳跃表中的排位,计算方法是:将查找次节点过程中经过的所有层的span相加。如果查找节点4,从节点1开始。路径为:节点1的L5 -> 节点4的L5,span=3,那么节点4的排位=3
backforward :后退指针。图中的BW。用于从表尾开始遍历到表头。
zkiplistlevel 结构:前进指针。比如节点1的L5指向节点4的L5;span:跨度。比如节点1的L5到节点4的L5的跨度=3