跳表基础

raw/articles/2026/05/跳表基础

一句话总结

跳表(Skip List)通过空间换时间思想,在原始链表上构建多层索引,将查询、插入、删除操作的时间复杂度从 $O(N)$ 优化到 $O(\log N)$,实现难度远低于自平衡二叉搜索树。

核心原理

问题背景

普通单链表中,通过索引查询对应节点需要从头结点开始逐个遍历,时间复杂度为 $O(N)$。即使拿到目标节点后的增删改操作只需 $O(1)$,查找的瓶颈导致整体效率低下。

跳表设计

跳表在原始链表基础上增加多层索引

  • 每向上一层,索引节点数量减少一半,索引间隔变为 2 倍
  • 索引高度为 $\log N$($N$ 为链表元素个数)

示例结构

indexLevel   0,,,,,,,--8,--10
indexLevel   0,,,--4,,,--8,--10
indexLevel   0,--2,--4,--6,--8,--10
indexLevel   0--1--2--3--4--5--6--7--8--9--10
nodeLevel    a->b->c->d->e->f->g->h->i->j->k

查询过程(以查索引 7 为例)

  1. 最高层:区间 [0, 8] 包含 7,从节点 0 进入下一层
  2. 第二层:从节点 0 开始,[0, 4] 不包含 7,移动到节点 4;[4, 8] 包含 7,进入下一层
  3. 第三层:从节点 4 开始,[4, 6] 不包含 7,移动到节点 6;[6, 8] 包含 7,进入下一层
  4. 第四层:从节点 6 开始,[6, 7] 包含 7,找到目标节点 h

复杂度分析:经过 $\log N$ 层,每层移动不超过 2 次,总时间复杂度 $O(\log N)$。

时间复杂度对比

操作 普通链表 跳表
查询(按索引) $O(N)$ $O(\log N)$
插入 $O(N)$(查找+$O(1)$插入) $O(\log N)$
删除 $O(N)$(查找+$O(1)$删除) $O(\log N)$
修改 $O(N)$ $O(\log N)$

关键补充

  1. 动态索引调整:插入和删除时需动态调整索引层节点,保证每层索引区间尽可能二分,否则时间复杂度会退化
  2. 通用场景:跳表不仅可按索引查找,还可用于有序键值对的存储和查找,应用场景与二叉搜索树类似
  3. 实现复杂度:跳表的代码实现比自平衡二叉搜索树(如红黑树)简单很多

与二叉搜索树对比

维度 跳表 自平衡二叉搜索树
时间复杂度 $O(\log N)$ 增删查 $O(\log N)$ 增删查
实现难度 简单 复杂(需处理旋转等操作)
适用场景 有序键值存储 有序键值存储
并发友好 较好(无需全局平衡) 较差

相关概念

相关实体


Interactive Graph