Skip to content

Cuckoo Hashing

cuckoo hashing · 布谷鸟哈希

为每个键提供两个候选槽,以踢出链和必要的重哈希换取常数最坏查找。

条目类型
模型

形式陈述

Cuckoo Hashing 是哈希表中的开放定址方案:每个键只允许落在少数候选位置,查询因此只检查常数个槽位,插入则通过重定位链恢复这一位置约束。

两位置不变量

两个来自合适通用哈希族的独立函数给键 x 候选槽 h1(x)h2(x)。每个键必须存于二者之一,因此查找只检查两处,最坏 O(1)。插入把键放入一个候选槽,若占用就踢出旧键,旧键转到自己的另一位置;遇到环或步数阈值后重新选择哈希函数并重建。

Cuckoo 图刻画

把两张表的槽作为一个的二分两侧顶点,每个键作为连接两个候选槽的边。为每条边选择一个端点存放,且每顶点容量一;经典单槽模型可成功放置,当且仅当每个连通分量的边数不超过顶点数,即分量至多含一个环。树分量沿路径定向即可,双环分量必有某槽承担两键。

直觉

每个键像一条连接两个候选槽的边,选择存储位置就是把这条边定向到一个端点。踢出链沿着当前定向寻找可改道的路径;若某个分量的边比槽还多,无论从哪一键开始踢都不可能成功,循环只是容量障碍在执行过程中的表现。

Cuckoo 哈希的 kick-out 链
例子与边界

踢出路径例子

新键 x 占用 h1(x) 并踢出 yy 转到 h2(y) 又踢出 z;若 z 的另一槽为空,整条交替路径完成。若路径回到已经出现的状态,继续踢只会循环,必须 rehash,而不是声称插入仍为最坏常数。

概率与装载边界

在低于经典阈值、哈希足够随机时,插入期望摊还常数;接近阈值时复杂分量和长路径概率迅速增加。桶化 cuckoo、更多候选和 stash 改变阈值与查询位置数,须另写模型。查询的常数最坏界不含重建期间的并发语义;Las Vegas 版本通过重试保证结果正确,但运行时间随机。

推论与应用

候选位置由随机哈希函数决定,插入失败概率和重哈希次数因此属于随机化算法分析。查询的常数探测是条件性的:它依赖当前表已经成功构造,并不消除构造阶段的随机失败事件。

Rehash 的摊还语义

检测到环后,给当前全部键重新抽一对哈希函数并从空表构建;若仍失败继续重试。只要装载低于相应随机图阈值,单次全表构建成功概率有常数下界,所以重试次数期望常数,重建总成本可向自上次扩容以来的插入摊还。

这个结论要求失败时更换函数,而不是沿同一环从另一个起点继续踢。扩容也改变图顶点数和阈值。若系统要求每次插入最坏延迟,需要增量 rehash、stash 或 deamortization,并重新说明查询要检查哪些旧/新位置。

失败分量怎样被识别

设候选槽为 a,b,c,已有键对应边 (a,b)(b,c)(c,a)。三条边构成单环,仍可沿环给每条边选不同端点;再插入候选同为 (a,b) 的键后,分量有 4 条边却只有 3 个顶点,容量一放置必然失败。踢出过程反复回到旧状态只是这一图条件的运行时表现。

实现可按以下顺序处理:

  1. 限制一次踢出的最大步数,并记录本轮访问状态;
  2. 超限后把新键和被踢出的键一起保留在临时区,不能丢失;
  3. 抽取新哈希函数,从空表重插全部键;
  4. 若仍遇坏分量则重试,达到负载阈值时先扩容。

查找只检查两个槽的最坏 O(1) 与插入的期望摊还 O(1) 是两种不同保证。若加入 stash,查询还必须检查 stash;若后台增量重建,查询需同时检查新旧表,不能继续声称接口完全未变。

参考资料
  • Rasmus Pagh, Flemming Friche Rodler, Cuckoo Hashing, Journal of Algorithms, 2004.
  • Michael Mitzenmacher, Some Open Questions Related to Cuckoo Hashing, ESA, 2009.
关系图谱14 个相邻概念 · 4 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
分类位置

上位 / 更一般

下位 / 直接特例

暂未标注直接特例。

类型化关系