跳跃表

转自:http://www.redisbook.com 

跳跃表

跳跃表(维基百科):

html

从图中能够看到, 跳跃表主要由如下部分构成:redis

  • 表头(head):负责维护跳跃表的节点指针。算法

  • 跳跃表节点:保存着元素值,以及多个层。数据结构

  • 层:保存着指向其余元素的指针。高层的指针越过的元素数量大于等于低层的指针,为了提升查找的效率,程序老是从高层先开始访问,而后随着元素值范围的缩小,慢慢下降层次。ide

  • 表尾:所有由 svg

  • 容许重复的 member 的 score 值,还要检查 score 值能够重复时,单靠 member 域都一并检查才行。函数

  • 每一个节点都带有一个高度为 1 层的后退指针,用于从表尾方向向表头方向迭代:当执行 ZREVRANGEBYSCORE 这类以逆序处理有序集的命令时,就会用到这个属性。this

这个修改版的跳跃表由 redis.h/zskiplistNode 定义: 
spa

typedef struct zskiplistNode {

    // member 对象
    robj *obj;

    // 分值
    double score;

    // 后退指针
    struct zskiplistNode *backward;

    // 层
    struct zskiplistLevel {

        // 前进指针
        struct zskiplistNode *forward;

        // 这个层跨越的节点数量
        unsigned int span;

    } level[];

} zskiplistNode;指针

如下是操做这两个数据结构的 API ,它们的做用以及相应的算法复杂度:

函数 做用 复杂度
zslFreeNode 释放给定的跳跃表节点 最坏 O(1)
zslFree 释放给定的跳跃表 最坏 O(N)
score 和 zslDeleteNode 删除给定的跳跃表节点 最坏 O(N)
member 和 zslFirstInRange 找到跳跃表中第一个符合给定范围的元素 最坏 O(N) 平均 O(logN)
zslDeleteRangeByScore 删除 zslDeleteRangeByRank 删除给定排序范围内的全部节点 最坏 O(N2)
zslGetElementByRank 根据给定排位,返回该排位上的元素节点 最坏 O(N) 平均 O(logN)

跳跃表的应用

和字典、链表或者字符串这几种在 Redis 中大量使用的数据结构不一样, 跳跃表在 Redis 的惟一做用, 就是实现有序集数据类型。

跳跃表将指向有序集的 member 域的指针做为元素, 并以 x 、 z 三个 6 、 15 分别建立三个 member 和 member 和 member 和 有序集》章节。

小结

  • 跳跃表是一种随机化数据结构,它的查找、添加、删除操做均可以在对数指望时间下完成。

  • 跳跃表目前在 Redis 的惟一做用就是做为有序集类型的底层数据结构(之一,另外一个构成有序集的结构是字典)。

  • 为了适应自身的需求,Redis 基于 William Pugh 论文中描述的跳跃表进行了修改,包括:

  1. score 和 <tt literal"="" style="background-color: transparent; color: rgb(34, 34, 34); font-size: 1.1em;">memeber 。

  2. 每一个节点带有高度为 1 层的后退指针,用于从表尾方向向表头方向迭代。

相关文章
相关标签/搜索