跳表的原理和时间复杂度,为什么还需要字典结构配合?

文章内容收录到个人网站,方便阅读hardyfish.top/

跳表(SkipList)是 一种有序链表的多级索引结构 ,通过增加多层索引来加快查找速度。

  • 最底层:完整的有序链表(包含所有元素)。
  • 上层索引 :抽取部分节点作为快捷通道,减少查找步数。
  • 查找过程:从最高层索引开始,能向右就向右,不能向右就向下,直到找到目标或最接近的位置。

举例(每层越上节点越少):

yaml 复制代码
Level 3:  1 ---------  9
Level 2:  1 --- 5 ---  9
Level 1:  1  3  5  7  9

找元素 7 的过程:

  • 从 Level 3 的 1 → 9(超了,往下)
  • Level 2 的 1 → 5 → 9(超了,往下)
  • Level 1 的 5 → 7(找到)

时间复杂度

跳表的平均性能和 平衡二叉树(AVL/红黑树) 类似:

操作 平均复杂度 最坏复杂度
查找 O(log N) O(N)
插入/删除 O(log N) O(N)
范围查询 O(log N + m) O(N)

m 为返回的结果数量。

在随机化层数 + 合理概率(Redis 用 1/4)下,O(N) 出现概率极低。

为什么 ZSet 还需要 字典结构(hash) 配合

在 Redis 的有序集合 ZSet 里,底层是 跳表(skiplist) + 字典(dict) 组合:

  • 跳表

    • 按分值(score)排序。
    • 支持范围查询(如 ZRANGEBYSCORE)。
    • 插入、删除、按排名查询效率高。
  • 字典

    • key:成员(member)
    • value:分值(score)
    • O(1) 时间 根据成员查分值(比如 ZSCOREZREM 先定位成员)。
    • 跳表按 score 排序,没法快速通过成员查 score,所以需要字典辅助。

为什么不只用跳表?

  • 如果只用跳表,查一个成员的分值需要 O(logN),而有了字典就是 O(1)。
  • 删除成员时,需要先 O(1) 定位到 score,再 O(logN) 从跳表删除,整体性能更好。

总结一句话

跳表保证了 有序存储 + 范围查询的高效性 ,字典保证了 按成员快速定位

Redis 的 ZSet 用 双结构冗余存储 ,是空间换时间的设计,既能 O(1) 找成员,又能 O(logN) 做有序操作。

相关推荐
芝士爱知识a3 小时前
2026年AI面试软件推荐
人工智能·面试·职场和发展·大模型·ai教育·考公·智蛙面试
毕设源码-朱学姐4 小时前
【开题答辩全过程】以 基于JavaWeb的网上家具商城设计与实现为例,包含答辩的问题和答案
java
石去皿5 小时前
大模型面试通关指南:28道高频考题深度解析与实战要点
人工智能·python·面试·职场和发展
C雨后彩虹5 小时前
CAS与其他并发方案的对比及面试常见问题
java·面试·cas·同步·异步·
美团程序员5 小时前
80道经典常见测试面试题
软件测试·面试·职场和发展·软件测试面试
测试秃头怪5 小时前
面试大厂就靠这份软件测试八股文了【含答案】
自动化测试·软件测试·python·功能测试·面试·职场和发展·单元测试
测试杂货铺5 小时前
软件测试面试题大全,你要的都在这。。
自动化测试·软件测试·python·功能测试·面试·职场和发展·测试用例
职豚求职小程序5 小时前
校园招聘——荣耀2025秋招,有哪些值得注意的信息?(含荣耀笔面试攻略)
面试·职场和发展
java1234_小锋6 小时前
Java高频面试题:SpringBoot为什么要禁止循环依赖?
java·开发语言·面试
2501_944525546 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter