什么是跳表
跳跃表是一种有序数据结构,通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。
跳表结构
假设有如下链表:

对初始链表做一层“索引”,每两个节点提取一个节点到上一层,然后用down指针连接到下一层。如下图:

现在我们查询16这个节点。从第一级索引开始,找到13,并且下一个为17,显然16在这两个节点之间,利用down指针下降一层,这次我们遍历2次即可。利用索引后,遍历了5+2=7次,而原始链表需要10次,这里加一层索引遍历次数减少了,效率提高了一点,但还不够,我们继续往上添加索引层。

如上图,采用二级索引时,查询16这个节点,现在只需要6次了。
跳表就是在链表的基础上建立多层索引,提高查询效率。链表的查询复杂度为O(n),而跳表查询复杂度可以达到O(logn)。同时跳表占用了更多空间,空间复杂度为O(n)。跳表插入时间复杂度也是O(logn),单链表插入复杂度为O(1),但是这是指插入动作,并不包含查找插入点所耗的时间,加上查找时间O(n)跳表效率还是高一点。跳表删除相对复杂些,需要删除数据需要更新各级索引。
跳表应用
Reids中使用跳表
Redis zset数据类型内部编码可以是压缩列表(ziplist)或跳跃表(skiplist)。除了跳跃表,实现有序数据结构的另一种典型实现是平衡树;大多数情况下,跳跃表的效率可以和平衡树媲美,且跳跃表实现比平衡树简单很多,因此redis中选用跳跃表代替平衡树。
Redis的跳跃表实现由zskiplist和zskiplistNode两个结构组成:前者用于保存跳跃表信息(如头结点、尾节点、长度等),后者用于表示跳跃表节点。
zset数据类型中当集合中元素数量大于128个或有序集合中存在成员长度都大于64字节时,zset转换成跳表实现。
参考:
https://yq.aliyun.com/articles/701175




