跳跃表

作者: Vic_is_new_Here | 来源:发表于2019-06-16 11:44 被阅读0次

    redis中有序集合zset是用跳跃表实现的,所以今天学习了一下跳跃表。本文主要讲redis中跳跃表的实现。

    一、结构

    跳跃表由两个结构组成,zskiplist和zskiplistnode,zskiplist用于保存跳跃表相关节点的信息,zskiplistnode用于保存跳跃表节点。

    1. zskiplist以下几个属性

        a. header:指向跳跃表头的节点。

        b. tail:指向跳跃表尾的节点。

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

        d. length:记录跳跃表的长度,也即是,跳跃表目前包含节点的数量(表头节点不计算在内)。

    2. zskiplistnode有以下几个属性

        a. level:表示跳跃表节点的各个层。每个层又有两个属性,forward(前进)指针和跨度。

        b. backward:表示指向后一个节点(也即指向表头方向)的后退指针。

        c. score:分值,在整个表中,分值可以重复。

        d. obj:成员对象,在整个表中,成员对象不可以重复。

    跳跃表结构图

    注意:

    1). 跳跃表各个 zskiplistnode的排序方式是根据分值大小来的,最小的排左边,依次往右排。如果分值相同,那么会成员对象大小来排(成员对象保存着一个SDS).

    2). 表头节点层数为32,其它节点定义层数的规则是根据幂次定律(power law,越大的数出现的概率越小)来的,生成一个大小介于1-32之间的数。

    二、应用

    跳跃表查找数据步骤图

    如图,要查找分值为41的节点

    1. 先找到最高层的节点23,与其比较,看23是否比要查找的数字小,是则将指针(因为redis底层由C语言实现)指向它,否则降层(指针下移)再比较。此处将指针指向23表示的节点。

    2. 发现L6, L5, L4都没有其他节点,就降层到L3层,与L3层指向的41分值表示的节点进行比较,发现相等,于是就找到了要查找的数据。

    注意:如果要插入数据,找到相应的位置后,生成节点,根据幂次定律随机生成层数就可以了;如果是要删除数据,那么会将整个层都删掉。

                                                                                                                                       2019-06-16

    相关文章

      网友评论

          本文标题:跳跃表

          本文链接:https://www.haomeiwen.com/subject/mnbwfctx.html