Redis底层结构三之有序集合的底层实现-跳跃表

跳跃表是一种用于有序集合的底层实现,其通过分层结构加快查找效率,查找、插入和删除操作的时间复杂度均为O(logn)。Redis中的跳跃表由zskiplistNode和zskiplist结构定义,支持快速访问头节点、尾节点以及获取表的长度和高度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 跳跃表(重点)

跳跃表是有序集合(sorted-set)的底层实现,效率高,实现简单。

跳跃表的基本思想: 将有序链表中的部分节点分层,每一层都是一个有序链表。

查找

在查找时优先从最高层开始向后查找,当到达某个节点时,如果next节点值大于要查找的值或next指针指向null,则从当前节点下降一层继续向后查找。

举例:

查找元素9,按道理我们需要从头结点开始遍历,一共遍历8个结点才能找到元素9。

第一次分层:

遍历5次找到元素9(红色的线为查找路径)

第二次分层:

遍历4次找到元素9

第三层分层:

遍历4次找到元素9

 这种数据结构,就是跳跃表,它具有二分查找的功能。

插入与删除

跳表插入的时间复杂度为:O(logn),支持高效的动态插入。

在单链表中,一旦定位好要插入的位置,插入结点的时间复杂度是很低的,就是O(1)。

但是为了保证原始链表中数据的有序性,我们需要先找到要插入的位置,这个查找的操作就会比较耗时。

对于纯粹的单链表,需要遍历每个结点,来找到插入的位置。但是对于跳表来说,查找的时间复杂度为O(logn),所以这里查找某个数据应该插入的位置的时间复杂度也是O(logn),

删除 找到指定元素并删除每层的该元素即可

跳跃表特点:

每层都是一个有序链表

查找次数近似于层数(1/2)

底层包含所有元素

空间复杂度 O(n) 扩充了一倍

Redis跳跃表的实现

//跳跃表节点
typedef struct zskiplistNode {
    //存储字符串类型数据 redis3.0版本中使用robj类型表示,但在redis4.0.1中直接使用sds类型表示 

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

//链表
typedef struct zskiplist{
    //表头节点和表尾节点
    structz skiplistNode *header, *tail; //表中节点的数量
    unsigned long length; //表中层数最大的节点的层数
    int level;
}zskiplist;

跳跃表的优势: 1、可以快速查找到需要的节点 O(logn)

2、可以在O(1)的时间复杂度下,快速获得跳跃表的头节点、尾结点、长度和高度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值