跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。支持平均O(logN)、最坏O(N)复杂度的节点查找,还可以通过顺序性操作来批量处理节点。
Redis只在两个地方用到了跳跃表,一个是实现有序集合键,另一个是在集群节点中用作内部数据结构。
5.1 跳跃表的实现 39
Redis的跳跃表由redis. h/ zskiplistNode和redis. h/ zskiplist两个结构定义,其中zskiplistNode结构用于表示跳跃表节点,而zskiplist结构则用于保存跳跃表节点的相关信息,比如节点的数量,以及指向表头节点和表尾节点的指针等等。
5.1.1跳跃表节点
typedef struct zskiplistNode {
struct zskiplistLevel { // 层
struct zskiplistNode *forward; // 前进指针
unsigned int span; // 跨度 (记录两个节点之间的距离)
} level[];
struct zskiplistNode *backward; // 后退指针(每次只能后退至前一个节点)
double score; // 分值(double类型的浮点数,排序的依据)
robj *obj; // 成员对象(唯一性)
} zskiplistNode;
5.1.2跳跃表
typedef struct zskiplist {
struct zskiplistNode *header, *tail; // 表头节点和表尾节点
unsigned long length; // 表中节点的数量
int level; // 表中层数最大的节点的层数(1至32之间的随机数)
} zskiplist;
5.2 跳跃表API 44
5.3 重点回顾 45
- 跳跃表是有序集合的底层实现之一。
- Redis 的跳跃表实现由zskiplist和zskiplistNode两个结构组成,其中zskiplist用于保存跳跃表信息(比如表头节点、表尾节点、长度),而zskiplistNode则用于表示跳跃表节点。
- 每个跳跃表节点的层高都是1至32之间的随机数。
- 在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的。
- 跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序。