跳跃表在每个节点中维持多个指向其他节点的指针,可快速访问节点且有序
跳跃表查找复杂度为平均O(logN),最坏O(N)
跳跃表使用于有序集合元素数量比较多或者元素是比较长的字符串的场景。
跳跃表节点
typedef struct zskiplistNode{
//层
struct zskiplistNode{
//前进指针
struct zskiplistNode *forward
//跨度
unsigned int span;
} level[];
//后退指针
struct zskiplistNode *backward
//分值
double score;
//成员对象
robj *obj;
} zskiplistNode;
header: 指向跳跃表头节点
tail: 指向跳跃表尾节点
level : 记录跳跃表内层数最大的节点的层数
length : 跳跃表节点数量
层:每个层都包含前进指针和跨度,前进指针指向表尾方向的其他节点,跨度是记录前进指针指向的节点和当前节点的距离。
后退指针:用BW标记,指向当前节点的前一节点
分值:节点中保存的分值,节点按各自保存的分值由小到大排列
在跳跃表中,各节点保存的成员对象必须唯一,但多个节点保存的分值却可以相同,分值相同的节点将按照成员对象在字典序中的大小排列,从小到大排序。
跳跃表实现
type def struct zskiplist{
structz skiplistNode *header,*tail;
//节点数量
unsigned long length;
//层数最大节点的层数
int level;
} zskiplist;
跳跃表常用API
函数 | 作用 | 时间复杂度 |
---|---|---|
zslCreate | 新建跳跃表 | O(1) |
zslFree | 添加新节点 | 平均O(logN),最坏O(N) |
zsldellte | 删除节点 | 平均O(logN),最坏O(N) |
zslGetRank | 返回节点在跳跃表中排位 | 平均O(logN),最坏O(N) |
zslGetRank | 返回节点在跳跃表中节点 | 平均O(logN),最坏O(N) |
zslIsInRange | 给定分值范围,返回在该范围的所有节点 | O(1) |
zslDeleteRangeByScore | 给定分值范围,删除在该范围的所有节点 | O(N) |