跳表通过多层链表结构实现O(log n)查找:底层含全部有序节点,上层为稀疏子集构成快车道;节点携带多层指针支持垂直下降与水平推进;插入时用概率随机决定层数,避免重平衡开销。
跳表的多层结构不是简单堆叠几条链表,而是靠“分层索引 + 随机层数”协同工作,让查找从线性扫描变成逐级跳跃。核心在于每层是下一层的稀疏子集,且插入时用概率决定节点出现在哪些层,避免重平衡开销。
多层链表怎么组织才有效
最底层(Level 0)必须包含全部有序数据节点,比如 1 → 3 → 5 → 7 → 9 → 12 → 17 → 19 → 21 → 25。往上每一层都是它的“快车道”:
- Level 1 可只保留部分节点,如 1 → 7 → 12 → 19 → 25,跨度不等距,但整体覆盖均匀
- Level 2 更稀疏,如 1 → 12 → 25,用于大范围定位
- 顶层(如 Level 3 或 Level 4)通常只有头尾或极少数节点,起快速入口作用
关键点:高层不要求严格按固定步长抽点,而是靠后续随机机制自然维持稀疏性与覆盖性之间的平衡。
节点怎么设计才能跨层关联
每个节点需携带多个指针,支持在不同层级中定位自身及相邻节点:
- next:指向同层下一个节点
- down:指向下一层对应位置的节点(同一数据值)
- up:指向上一层对应节点(可选,便于删除时回溯)
- backward(Redis 风格):支持反向遍历,用于范围查询
例如值为 12 的节点,在 Level 2 有 next 指向 25,在 Level 1 有 down 指向 Level 1 的 12 节点,在 Level 0 同样存在并连着 9 和 17。这样查找时能“垂直下降 + 水平推进”无缝切换。
插入新节点时如何决定它该上几层
不靠人工规划,而用概率方式生成层数,典型做法是“抛硬币直到反面出现”:
- 设晋升概率 p = 0.5,则层数为 1 的概率是 50%,为 2 是 25%,为 3 是 12.5%……
- 实际实现中限制最大层数(如 Redis 用 32,C 实现常用 8 或 16),防止极端情况
- 插入前先掷出目标层数 k,然后从最高层开始,沿各层找到插入点,再逐层新建指针连接
这种机制让结构天然具备统计平衡性——不需要像红黑树那样旋转或染色,也不用像 B+ 树那样分裂合并。
查找过程为什么能逼近 O(log n)
查找不是从底层扫起,而是自顶向下“跳-降-跳-降”:
- 从最高层 head 出发,沿 next 向右走,一旦 next→data > 目标值,就停住
- 立刻 down 到下一层,从当前节点继续向右找
- 重复直到 Level 0,最后一步做精确比对
查 21 的例子:Level 2 从 1 → 9 → 21(命中);若查 17,则 Level 2 走到 9 后发现 21 > 17,降层到 Level 1 的 9,再 → 17;整个路径跳过大量中间节点,平均步数约 log₂n。
不复杂但容易忽略:层级越多不一定越快,过高层数会增加指针存储和插入开销;合理设置最大层数与晋升概率,才能在空间和时间之间取得实用平衡。


















