介绍
通过在每个节点中维持多个指向其他节点的指针,从而快速访问节点
查找速度:平均O(log N),最坏O(N)
支持顺序性操作
使用跳跃表作为有序集合键的底层实现之一
性质
- 每一层都是一个有序的链表,最底层(L1)的链表包含所有元素
- 如果一个元素出现在第 n 层的链表中,则它也出现在第 n+1 层
- 搜索先从上层搜索,当前面的元素比target大时,则向下一级搜索(即向着更密集的数据找)
- 总体来看从左上往右下寻找
实现
level:表中层数最大的节点的层数
length:节点数量
跳跃表节点
typedef struct zskiplistNode
{
struct zskiplistNode * backward;//后退指针
double score;//分值
robj * obj;//成员对象
struct zskiplistLevel //层
{
struct zskiplistNode * forward; //前进指针
unsigned int span;//跨度
}
}
层
level数组可以包含多个元素,每个元素都包含一个指向其他节点的指针,来加快访问其他节点的速度
感觉幂次规律,随机生成一个[1,32]的值作为level数组的大小,即层的高度
前进指针
每个层都有一个指向表尾方向的前进指针(level[i].forward)
跨度
记录两个节点之间的距离
指向NULL的所有前进指针的跨度都为0
跨度实际是用来计算排位的:在查找某个节点过程中,将沿途访问的所有层的跨度累积起来,得到的结果就是目标节点在跳跃表中的排位(即该节点是第几个节点)
后退指针
可以先通过跳跃表的tail指针访问表尾节点,然后通过后退指针访问倒数第二个节点…,直到遇到指向NULL的后退指针
分值和成员
- 分值:跳跃表中所有节点都按分值从小到大排序
- 成员对象:指向SDS字符串对象的指针
- 跳跃表中成员对象必须唯一,但是分值可以相同
- 分值相同的节点按照成员变量的字典序排序
跳跃表
typedef struct zskiplist
{
struct zskiplistNode * header,*tial;
unsigned long length;//表中节点的数量
int level;//表中层数最大的节点的层数
} zskiplist;
使得能O(1)访问表头表尾节点,访问跳跃表长度,获取表中层数最大的节点的层数
t level;//表中层数最大的节点的层数
} zskiplist;
使得能O(1)访问表头表尾节点,访问跳跃表长度,获取表中层数最大的节点的层数