【Redis】跳表结构
目录
- 1、背景
- 2、跳表
- 【1】底层结构
- 【2】关键操作
- 【3】redis使用跳表原因
- 【4】特性
1、背景
redis中的跳表是一种有序数据结构,主要用于实现有序集合(zset)。跳表通过多级索引实现高效查找(平均O(logN)时间复杂度),同时保持插入和删除的高效性,下面就来讲解一下跳表(redis版本6.2.18)的底层结构。
2、跳表
【1】底层结构
跳表节点结构体如下:
typedef struct zskiplistNode {sds ele; //存储的元素double score; //排序分值,节点按score升序排列struct zskiplistNode *backward; //后向指针(单向链表,用于从尾到头遍历)struct zskiplistLevel {struct zskiplistNode *forward; //前向指针unsigned long span; //当前节点到下一个节点的跨度} level[]; //层级数组
} zskiplistNode;
跳表结构体如下:
typedef struct zskiplist {struct zskiplistNode *header, *tail; //指向跳表节点的头尾节点(头节点是虚拟节点,不存储数据)unsigned long length; //跳表中元素数量int level; //跳表实际使用的最高层数
} zskiplist;
【2】关键操作
跳表的关键操作有如下几种:
1、查找:从高层开始向右遍历,若下一节点分值大于目标值,则下降一层
2、插入:随机生成节点层数,更新前后指针和跨度
3、删除:类似插入的逆向操作
【3】redis使用跳表原因
redis使用跳表而不使用红黑树因为:
1、平衡性:相比红黑树,跳表实现更简单,且支持范围查询
2、性能:与红黑树的查找/插入均为O(logN),但跳表更适合并发场景(Redis6.0后支持多线程)
【4】特性
跳表的特性如下:
特性 | 说明 |
---|---|
数据结构用途 | 实现有序集合的核心数据结构之一 |
时间复杂度 | 查找/插入/删除:平均O(logN),最坏O(N) |
空间复杂度 | 平均O(N)(每个节点需存储多级指针) |
层数控制 | 节点层数随机生成,高层稀疏,低层密集 |
关键操作 | ZADD:插入节点并维护跳表结构- ZRANGE:按分值范围遍历- ZRANK:利用 span 计算排名 |
与红黑树相比 | 优势:实现简单,天然支持范围查询- 劣势:空间占用略高 |
并发支持 | Redis 6.0+ 多线程模式下,跳表操作仍为单线程(由主线程处理) |