Redis学习(4)——跳跃表(skiplist)

一,何为跳跃表

跳跃表(skiplist)是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。它的效率可以媲美平衡树,跳跃表的平均复杂度O(logN)最坏情况复杂度O(N),并且其原理和代码都要比平衡树更加简单,因此很多地方多用跳跃表代替平衡树。

二,在Redis中的应用

1,Redis使用跳跃表作为有序集合键的底层实现的数据结构之一。

1)当有序集合元素成员时较长的字符串时。

2)当有序集合包含元素很多时。

2,同时Redis也使用跳跃表在集群节点中用作内部数据结构。

(Redis只在这两个地方使用了跳跃表)

三,跳跃表的实现

(一),Redis的跳跃表由redis.h/zskiplistNode(跳跃表节点)和redis.h/zskiplist(跳跃表)两个结构定义。

一个跳跃表图例:(最左边含有header和tail指针的是跳跃表,左边四个是跳跃表节点)

(二)跳跃表节点的源代码和各个属性简介

typedef struct zskiplistNode{
   
     //层
    struct zskiplistLevel{
    //前进指针
        struct zskiplistNode *forward;
    //跨度
    unsigned int span;
    } level[];
    
    //后退指针
    struct zskiplistNode *backforward;

    //分值
    double score;
    
    //成员对象
    robj *obj;
}zskiplistNode;

1,层(level),前进指针(层指针,level[i].forward),跨度(level[i].span)

这里的跳跃表节点的层数组是一个柔性数组,可以包含多个元素,每个元素都包含一个层指针(level[i].forward),指向该结点在本层的后继结点。该指针用于从表头向表尾方向访问结点,它可以一次跳过自身节点后的多个节点。可以通过这些层指针来加快访问结点的速度。这里,Redis中的跳跃表和其他一般跳跃表不同的地方在于使用了跨度(level[i].span),而跨度记录了前进指针level[i].forward所指向的节点和当前节点的距离。通过跳跃表结点的层跨度,可以快速得到该结点在跳跃表中的排名。

层数组的大小遵循幂次定律(power law,越大的数出现的几率越小)随机生成一个介于1和32之间的值作为层数组大小。

2,后退指针(backward)

Redis跳跃表区别于普通跳跃表还有个后退指针(zskiplistNode.backward),用于从表尾向表头方向访问节点。并且每个后退指针只指向自身节点的前一个节点,构成了一个链表。

3,分值(score)和成员对象(obj)

分值(score)属性是一个double类型的浮点数,跳跃表中的所有节点都按分值的大小排序。不同的节点可以有相同的分值,相同的分值会按照成员对象在字典序中的大小来排序。

成员对象(obj)是一个指针,它指向一个字符串对象,而字符串对象又保存了一个SDS值。不同的节点的成员对象是必须是不同的,即成员对象是唯一的。

(三)跳跃表的源代码和各个属性简介

跳跃表由多个跳跃节点组成。由zskiplist结构来组织这些节点,保存它们的一些信息,如:节点长度、节点数量。

typedef struct zskiplist{
    
    //表头节点和表尾节点
    struct skiplistNode *header, *tail;

    //表中的节点数量
    unsigned long length;
    
    //表中层数最大的节点的层数
    int level;
}zskiplist;

1,头指针(header)和尾指针(tail)

头指针(header)和尾指针(tail)分别指向跳跃表的表头结点和尾节点。通过这两个指针,定位表头结点和表尾结点的复杂度为O(1)。表尾结点是表中最后一个结点。而表头结点实际上是一个伪结点,该结点的成员对象为NULL,分值为0,它的层数固定为32(层的最大值)。

2,表中节点数量(length)

用来记录节点数量,使得获取表的节点数量的复杂度尾O(1)。

3,表中层数的最大值(level)

用于记录层数最大的节点的层数,使得获取层数最大的那个节点的层数量复杂度为O(1)(表头节点不计入,因为它的层数固定为32(层的最大值)。

 

Redis中跳跃表的一些具体操作的源代码实现推荐博文:https://blog.csdn.net/gqtcgq/article/details/50613896

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值