|  |
| --- |
| 系列条目 |
| 概率性数据结构 |
| * 布隆过滤器
* 跳跃列表
 |
| 随机树 |
| * 随机二叉树
* Treap
 |
| 
相关条目 |
| * 随机化算法
 |
|  資訊科技主题 |
| * 
* 论
* 编
 |

在计算机科学中，**跳跃列表**是一种数据结构。它使得包含n个元素的有序序列的查找和插入操作的平均时间复杂度都是O(\log n)，优于数组的O(n)复杂度。

快速的查询效果是通过维护一个多层次的链表实现的，且与前一层（下面一层）链表元素的数量相比，每一层链表中的元素的数量更少（见右下角示意图）。一开始时，算法在最稀疏的层次进行搜索，直至需要查找的元素在该层两个相邻的元素中间。这时，算法将跳转到下一个层次，重复刚才的搜索，直到找到需要查找的元素为止。跳过的元素的方法可以是随机性选择或确定性选择，其中前者更为常见。

描述
--

一张跳跃列表的示意图。每个带有箭头的框表示一个指针, 而每行是一个稀疏子序列的链表；底部的编号框（黄色）表示有序的数据序列。查找从顶部最稀疏的子序列向下进行, 直至需要查找的元素在该层两个相邻的元素中间。
跳跃列表是按层建造的。底层是一个普通的有序链表。每个更高层都充当下面列表的「快速通道」，这里在第i层中的元素按某个固定的概率p（通常为{\frac {1}{2}}或\frac{1}{4}）出现在第{\displaystyle i+1} 层中。每个元素平均出现在{\displaystyle {\frac {1}{1-p}}}个列表中，而最高层的元素（通常是在跳跃列表前端的一个特殊的头元素）在{\displaystyle \log \_{1/p}n}个列表中出现。

在查找目标元素时，从顶层列表、头元素起步。算法沿着每层链表搜索，直至找到一个大于或等于目标的元素，或者到达当前层列表末尾。如果该元素等于目标元素，则表明该元素已被找到；如果该元素大于目标元素或已到达链表末尾，则退回到当前层的上一个元素，然后转入下一层进行搜索。每层链表中预期的查找步数最多为\frac{1}{p}，而层数为{\displaystyle \log \_{1/p}n}，所以查找的总体步数为{\displaystyle -{\frac {\log \_{p}n}{p}}}，由于p是常数，查找操作总体的时间复杂度为{\displaystyle {\mathcal {O}}(\log n)\,}。而通过选择不同p值，就可以在查找代价和存储代价之间取得平衡。

跳跃列表不像平衡树等数据结构那样提供对最坏情况的性能保证：由于用来建造跳跃列表采用随机选取元素进入更高层的方法，在小概率情况下会生成一个不平衡的跳跃列表（最坏情况例如最底层仅有一个元素进入了更高层，此时跳跃列表的查找与普通列表一致）。但是在实际中它通常工作良好，随机化平衡方案也比平衡二叉查找树等数据结构中使用的确定性平衡方案容易实现。跳跃列表在并行计算中也很有用：插入可以在跳跃列表不同的部分并行地进行，而不用对数据结构进行全局的重新平衡。

### 实现细节

往跳跃列表中插入一个元素
因为跳跃列表中的元素可以在多个列表中，所以每个元素可以有多于一个指针。

跳跃列表的插入和删除的实现与普通的链表操作类似，但高层元素必须在进行多个链表中进行插入或删除。

跳跃列表的最坏时间性能具有一定随机性，但是可以通过时间复杂度为\mathcal{O}(n)的遍历操作（例如在打印列表全部内容时）以无随机的算法重整列表的结构，从而使跳跃列表的实际查找时间复杂度尽量符合理论平均值{\displaystyle {\mathcal {O}}(\log n)}。

除了使用无随机算法之外，我们可以以下面的准随机方式地生成每一层：

```
make all nodes level 1
j ← 1
**while** the number of nodes at level j > 1 **do**
  **for** each i'th node at level j **do**
    **if** i is odd 
      **if** i is not the last node at level j
        randomly choose whether to promote it to level j+1
      **else**
        do not promote
      **end if**
    **else if** i is even and node i-1 was not promoted
      promote it to level j+1
    **end if**
  **repeat**
  j ← j + 1
**repeat**
```

类似无随机版本，准随机重整仅在需要执行一个\mathcal{O}(n)操作（访问每个节点）的时候伴随进行。

历史
--

跳跃列表由威廉·普（英语：）发明。发明者对跳跃列表的评价是："跳跃列表是在很多应用中有可能替代平衡树而作为实现方法的一种数据结构。跳跃列表的算法有同平衡树一样的渐进的预期时间边界，并且更简单、更快速和使用更少的空间。"

参见
--

* 布隆过滤器
* 跳跃图（英语：）

参考文献
----

1. 1 2  Papadakis, Thomas.  (PDF) (学位论文). University of Waterloo. 1993  [2018-06-03]. （原始内容 (PDF)存档于2017-08-10）.
2. 1 2  Pugh, W.  (PDF). Communications of the ACM. 1990, **33** (6): 668  [2018-06-03]. doi:10.1145/78973.78977. （原始内容存档 (PDF)于2020-06-20）.
3. ↑  Munro, J. Ian; Papadakis, Thomas; Sedgewick, Robert.  (PDF).. Orlando, Florida, USA: Society for Industrial and Applied Mathematics, Philadelphia, PA, USA: 367–375. 1992  [2018-06-03]. doi:10.1145/139404.139478. （原始内容 (PDF)存档于2021-05-06）.

外部链接
----

* Description （页面存档备份，存于） from the Dictionary of Algorithms and Data Structures
* skip lists by Thomas Niemann
* Skip List（跳躍表）原理詳解與實現 - One thing I know,that is I know nothing.(Socrates Greek) - ITeye技術網站 （页面存档备份，存于）

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
数据结构 |
| --- |
|  |
| 类型 | 
* 集合
* 容器

 |
|  |
| 抽象类型 | 
* 关联数组
	+ 多重关连数组（英语：）
* 列表
* 堆栈
* 队列
	+ 双端队列
* 优先队列
	+ 双端优先队列
* 集合
	+ 多重集
	+ 併查集
* 可持久化数据结构
	+ 线段树

 |
|  |
| 数组 | 
* 字串
* 位数组
* 环形缓冲器
* 动态数组
* 哈希表
* 哈希数组树（英语：）
* 稀疏矩阵

 |
|  |
| 链（英语：） | 
* 关联表（英语：）
* 链表
* 跳跃列表
* 松散链表（英语：）
* 异或链表

 |
|  |
| 树 | 
* 线段树
* 自平衡二叉查找树
* B树
* 二叉树
	+ AA树
	+ AVL树
	+ 红黑树
	+ 平衡树
	+ 伸展树
	+ 二叉查找树
* 堆
	+ 二叉堆
	+ 左偏树
	+ 二项堆
	+ 斐波那契堆
* R树
	+ R\*树
	+ R+树
	+ Hilbert R树（英语：）
* 前缀树
	+ 哈希树

 |
|  |
| 图 | 
* 有向图
* 有向无环图
* 二元决策图
* 无向图
* 确定性非循环有限自动机（英语：）

 |
|  |
| 数据结构术语 |

 |