1.什么是跳跃表(Skip List)
跳跃表是 ZSet 有序列表底层的一种实现,也成为跳表。它通过添加多层链表的方式,用于在有序集合中进行高效的查找操作。
简单跳跃表的结构图:
从图中可以看出跳跃表有这些特征:
- 最底层是一个完整的有序链表;
- 下面的链表包含上面的链表;
- 上层链表和下层链表通过额外的指针来连接;
- 跳跃表的平均查找时间复杂度为 O(log n)。
面试官问,为什么使用跳跃表来作为有序列表的存储结构,而不使用链表或红黑树 ?
答:链表首先排除,他的查找时间复杂度为 O(n),红黑树的查找时间复杂度虽然也是 O(n),但是红黑树实现起来比跳跃表要复杂得多,并且红黑树的新增和删除操作,需要进行一些旋转操作,还要保证树的颜色满足一定规则,所以跳跃表才是不错的选择。
2. 跳跃表的查询和新增流程
2.1 跳跃表的查询流程
比如查询 value = 18 ,会从上往下找:
从上往下总共查找三次就找到 18 了,第一层的 3 到第二层的 3 经历了下移操作。
2.2 跳跃表的新增流程
要了解跳跃表的新增流程,首先得知道一个知识点:节点随机层数
什么是节点随机层数 ?
节点随机层数就是在执行添加流程之前,会先生成一个 1~32 之间的随机数,这个随机数决定了后续的新增流程需要在跳跃表里面新增多少层。
为什么要这样设计 ?
为了保证 Redis 的执行效率!!如果制定固定的规则,比如说上层链表必须是下层链表跨越两个节点的链表组成的,那么后续执行新增操作之后,还得保证每层链表都符合这个规则,这样就比较低效了,就类似于红黑树的左旋右旋,还要保证树的颜色满足规则了。
新增后的跳跃表:
它在新增之前,这个随机层数的生成也是有讲究的(了解):
- 生成 1 层的概率 50%
- 生成 2 层的概率 25%
- 生成 3 层的概率 12.5%
- 依次类推....