节点中用BW字样标记节点的后退指针,它指向位于当前节点的前一个节点。后退指针在程序从表尾向表头遍历时使用。与前进指针所不同的是每个节点只有一个后退指针,因此每次只能后退一个节点。
分值(score):
各个节点中的1.0、2.0和3.0是节点所保存的分值。在跳跃表中,节点按各自所保存的分值从小到大排列。
成员对象(oj):
各个节点中的o1、o2和o3是节点所保存的成员对象。在同一个跳跃表中,各个节点保存的成员对象必须是唯一的,但是多个节点保存的分值却可以是相同的:分值相同的节点将按照成员对象在字典序中的大小来进行排序,成员对象较小的节点会排在前面(靠近表头的方向),而成员对象较大的节点则会排在后面(靠近表尾的方向)。
2.2 Redis跳跃表常用操作的时间复杂度 操作 时间复杂度创建一个跳跃表 O(1)
释放给定跳跃表以及其中包含的节点 O(N)
添加给定成员和分值的新节点 平均O(logN),最坏O(logN)(N为跳跃表的长度)
删除除跳跃表中包含给定成员和分值的节点 平均O(logN),最坏O(logN)(N为跳跃表的长度)
返回给定成员和分值的节点再表中的排位 平均O(logN),最坏O(logN)(N为跳跃表的长度)
返回在给定排位上的节点 平均O(logN),最坏O(logN)(N为跳跃表的长度)
给定一个分值范围,返回跳跃表中第一个符合这个范围的节点 O(1)
给定一个分值范围,返回跳跃表中最后一个符合这个范围的节点 平均O(logN),最坏O(logN)(N为跳跃表的长度)
给定一个分值范围,除跳跃表中所有在这个范围之内的节点 平均O(logN),最坏O(logN)(N为跳跃表的长度)
给定一个排位范围,鼎除跳跃表中所有在这个范围之内的节点 O(N),N为被除节点数量
给定一个分值范固(range),比如0到15,20到28,诸如此类,如果跳氏表中有至少一个节点的分值在这个范間之内,那么返回1,否则返回0 O(N),N为被除节点数量
本文重点
跳跃表基于单链表加索引的方式实现
跳跃表以空间换时间的方式提升了查找速度
Redis有序集合在节点元素较大或者元素数量较多时使用跳跃表实现
Redis的跳跃表实现由 zskiplist和 zskiplistnode两个结构组成,其中 zskiplist用于保存跳跃表信息(比如表头节点、表尾节点、长度),而zskiplistnode则用于表示跳跃表节点
Redis每个跳跃表节点的层高都是1至32之间的随机数
在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序。
小结跳跃表可能对我们来说是一种的稍陌生的数据结构。本篇文章简单介绍了跳跃表这种数据结构,并且分析了Redis中跳跃表的使用。下篇文章将继续分享Redis中用到的数据结构整数集合。敬请关注!
参考《Redis设计与实现》
《Redis开发与运维》
《Redis官方文档》