跳跃表笔记

在redis中,有序集合zset使用了跳跃表,此外,集群节点中的内部数据结构也使用到了跳跃表

  1. 以空间换时间的一种优化链表算法 优化有序链表 时间复杂度:O(logN) 空间复杂度:2N
  2. 兼顾链表与数组优势的数据结构 索引: span的累加--->rank 作为索引
  3. 从内存占用上来说,skiplist比平衡树更少 AVL: 每个节点有2个指针 sl:每个节点有1/1-P=1.33 个指针 P:0.25

2.1、跳跃表的基本思想

跳跃表是有序集合(sorted-set)的底层实现,将有序链表中的部分节点分层,每一层都是一个有序链表。

  1. 分层,每层由有序链表构成
  2. 头节点在每层出现
  3. 某节点在上层出现,则在下层也出现
  4. 节点层数随机

2.2、节点与结构

跳跃表节点

typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;
  • ele:存储字符串数据
  • score:存储排序分值
  • backward:后退指针,指向当前节点最底层的前一个节点
  • level[]:柔性数组,随机生成1-64的值 forward:指向本层下一个节点
  • span:本层下个节点到本节点的元素个数

跳跃表链表

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;
    unsigned long length;
    int level;
} zskiplist;
  • zskiplistNode *header *tail:头节点和尾节点
  • length:跳跃表长度(不包括头节点)
  • level:跳跃表高度

zslInsert

插入节点:

  1. 从最上层开始遍历节点

  2. 如果 i 不是 zsl->level-1 层,那么 i 层的起始 rank 值为 i+1 层的 rank 值

  3. 如果当前分值大于下一个分值,则累加span(比对分值,如果分值一样就比对ele)ele按字典序

  4. 指向本层的下一个节点

  5. 记录新节点的前一个节点

  6. 调用zslRandomLevel函数获得一个随机层数

  7. 如果新节点层数大于跳跃表层高,那么初始化表头节点中未使用的层,并将它们记录到 update 数组中

  8. 创建新节点

  9. 将前面记录的指针指向新节点,并做相应的设置

  10. 设置新节点的 forward 指针

  11. 将沿途记录的各个节点的 forward 指针指向新节点

  12. 计算新节点跨越的节点数量

  13. 更新新节点插入之后,沿途节点的 span 值

  14. 未接触的节点的 span 值也需要增一,这些节点直接从表头指向新节点

  15. 设置新节点的后退指针

  16. 跳跃表的节点计数增一

  17. 返回新节点

    span:本次后驱节点跨越多少个第一层节点(包括跨越到的节点)

    rank也叫节点索引值,是span的累加值

    阶段1:查找要插入的位置

    阶段2:调整层高

    阶段3:生成节点并插入

    阶段4:设置backward

zslGetRank

查找排位:

  1. 排位就是累积跨越的节点数量
  2. 从最上层开始遍历节点并对比元素
  3. 如果当前分值大于下一个分值,则累加span(比对分值,如果分值一样就比对ele)ele按字典序
  4. 指向本层的下一个节点
  5. 如果找到了(ele相同)则返回

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值