Reidis——跳跃表

跳跃表

​ 跳跃表(skiplist)是一种有序的数据结构,它通过在每一个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的

​ 跳跃表查找节点的平均时间复杂度为O(lonN)、最坏为O(N),但需要维护几个指向其他节点的指针,空间复杂度为O(N),还可以通过顺序性操作来批量处理节点

​ 在大部分情况下,跳跃表的效率可以和二叉平衡树相同,并且跳跃表的实现较为简单

​ Redis使用跳跃表作为有序集合Zset的底层实现之一,当一个有序集合包含的元素数量较多或者一个元素的成员是比较长的字符串时,Redis就会使用跳跃表来作为有序集合的底层实现

​ Redis只在两个地方用到了跳跃表,一个是有序集合Zset ,另一个是在集群节点中用作内部数据结构

跳跃表的实现

​ Redis的跳跃表由redis.h/zskiplistNoderedis.h/zskiplist 两个结构体来定义,zskiplistNode表示跳跃表节点,zskiplist 表示跳跃表

  • 跳跃表
typedef struct zskiplist {
  //跳跃表的头节点和尾节点,头节点为一个标识辅助节点,指向跳跃表中第一个元素节点
  structz zskiplistNode *header,*tail;
  //跳跃表中节点的数量
  unsigned long length;
  //跳跃表中节点层级的最大值,即每个节点的Math.max(level.length)
  int level;
}zskiplist;
  • 跳跃表节点
typedef struct zskiplistNode {
  //后退指针,指向当前节点的前一个节点
  struct zskiplistNode *backward;
  //当前节点元素的分值
  double score;
  //当前节点保存的对象(不同的类型,如数字,字符串)
  robj *obj;
  //当前节点长度层级数组
  struct zskiplistLevel {
    //跳跃到下一个节点的指针,只能是向尾节点方向
    struct zskiplistNode *forward;
    //跳跃的跨度
    unsigned int span;
  }level[];
}zskiplistNode;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PL0ESAvd-1632553280688)(images/skiplist.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zKQ5UZMZ-1632553280690)(images/zskiplist.png)]

  • 跳跃表的层级都是1~32之间的随机数,一个跳跃表节点中的level层数采用抛硬币的方式决定该节点是否需要向上增加层级
  • 在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的
  • 跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值