跳表zskiplist

跳跃表是一种链式数据结构,在外观表现上其具有两个属性:分值和保存的对象。

跳跃表通过对每个节点的分值进行排序从而达到排序每个节点的目的,但这仅仅是其特点之一。

为了实现跳跃表的快速修改和查询操作,其内部还在每个节点上都保存了一个用于指向其后节点的指针数组,以及一个指向前一个节点的指针。

并且为了快速获取跳跃表的节点数目和指针数组的最大长度,其分别创建了一个length和一个level属性用于快速查询。

以下是跳跃表的数据结构:

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

//跳表节点
typedef struct zskiplistNode {
    // 成员对象
    robj *obj;
    // 分值   作为索引
    double score;
    // 后退指针
    struct zskiplistNode *backward;
    // 节点层结构 数组
    struct zskiplistLevel {
        // 前进指针
        struct zskiplistNode *forward;
        // 该层向前跨越的节点数量
        unsigned int span;
    } level[];
} zskiplistNode;

zskiplistNode保存了节点的分值,属性对象,后退指针以及指向其后节点的指针数组。

这里指针数组中的forward指向了从当前节点开始下一个具有同层级(与forward所在数组的位置相同的数组位置)的节点,而span则保存了forward指针从当前节点到下一个节点之间的跨度。

zskiplist主要保存了头结点,尾节点,节点数量和最大节点数组的层数,这里需要注意的是header指针中并没有保存实际的数据,但是其保存有指向下一个节点的指针和跨度。

如下是一个使用zskiplist保存数据的示例:

跳表zskiplist_第1张图片

跳表zskiplist_第2张图片

这里需要说明的是,跳跃表的节点数组的长度是随机的,其值为1到32之间的一个整数。跳跃表之所以能够与平衡树相媲美是因为其节点都是排序的,并且每个节点都有一个指向其后第一个拥有同层级的节点的指针。

redis学习参考资料:
Redis 设计与实现(第二版)

你可能感兴趣的:(redis,数据结构)