描述
跳跃表(skiplist)是对有序的链表增加上附加的前进链接,在列表中的查找可以快速的跳过部分列表,因此取名跳跃表。跳跃表大概就长得如下图所示
再举个形象点的栗子,就像我们如果要去国外,如果徒步去当然会累死,于是我们先坐飞机,下飞机后乘坐汽车,然后再走一段路最终到达目的地,于是我可以得到一张这样子的跳跃表:
其实说白了,无非就是一种加了索引的有序链表。而与有序链表最大的区别,
就是跳跃表增删查改的平均效率都是O(logN),在大部分情况下,跳跃表的效率可以和平衡树相媲美甚至更快,而实现比平衡树来的更为简单,当然更吃一些空间。如今有不少程序使用跳跃表来代替平衡树。
redis使用跳跃表作为有序集合键的底层实现之一。
源码解析
Redis的跳跃表实现由zskiplist和zskiplistNode两个结构组成,其中zskiplist用于保存跳跃表信息,zskiplistNode用于表示跳跃表结点
/* ZSETs use a specialized version of Skiplists */
/*
* 跳跃表节点
*/
typedef struct zskiplistNode {
// 成员对象
robj *obj;
// 分值
double score;
// 后退指针
struct zskiplistNode *backward;
// 层
struct zskiplistLevel {
// 前进指针
struct zskiplistNode *forward;
// 跨度
unsigned int span;
} level[];
} zskiplistNode;
/*
* 跳跃表
*/
typedef struct zskiplist {
// 表头节点和表尾节点
struct zskiplistNode *header, *tail;
// 表中节点的数量
unsigned long length;
// 表中层数最大的节点的层数
int level;
} zskiplist;
代码来自huangz注释的redis源码,地址在这里
https://github.com/huangz1990/redis-3.0-annotated
(跳跃表建立索引的方法等挖坑代填)