4、跳跃表

概念

跳跃表是一种有序的数据结构,它通过在每个节点维护多个指向其他节点的指针,以达到快速访问的目的。跳跃表支持平均O(logN)最坏O(N)的复杂度查找节点。大多数情况下,其性能可以和平衡树媲美。

跳跃表是有序集合键的底层实现之一,如果有序集合键包含的元素较多,或者成员是比较常的字符串的时候。Redis只有两个地方使用到了跳跃表:有序集合键、集群节点中用作内部数据结构。

结构描述

描述节点相关信息的zskiplist和存储节点的zskiplistNode

zskiplist中保存有 header(指向头结点)、tail(指向尾节点)、level(节点的最大层数,头结点除外)、length(节点数目,头结点除外)

zskiplistNode中又包含以下属性

typedef struct zskiplistNode{
    struct zskiplistNode* backward;       //后退指针:每一个节点都有一个后退指针,跨度为1
    double score;                         //分值:节点按照分值排序
    robj *obj;                            //成员对象
    struct askiplistLevel{                //层:每一个节点有许多层,每一层包含前进指针,和其跨度
        struct askiplistNode forward;
        unsigned int span;
    }level[];
}zskiplistNode;

1、层:每次生成一个跳跃表节点的时候,都会按照幂次定律(越大的数出现的几率越小)随机生成一个1~32之间的数作为level数组的大小,也就是层的高度。

2、前进指针:level[i].farword属性,遍历只需要使用前进指正就可以了

3、跨度:level[i].span属性,用来计算排位,将遍历的沿途所有的跨度相加就是排位。指向null的层跨度为0,因为没有指向任何对象。

4、后退指针,每次只可以后退一个跨度。从tail遍历,一直遇到null(head之后,排名第一的节点的后退指针不指向head,而是指向null,就像前面所述,head虽然有这些属性,但是不用)

5、成员对象是一个指针,它指向一个sds,跳跃表中的节点按照分值排序(从小到大),如果分值相同,则按照对象在字典中的排序来确定顺序。一个跳跃表中的两个节点之间,分值大小可以相同,但是成员对象必须是唯一的。

注意头结点也有上述的四个结构,但是其后退指针、分值、成员对象都没有用到

猜你喜欢

转载自blog.csdn.net/qq_24888697/article/details/81005463