“对每张表 $j\in{0,\ldots,L 1}$,抽取 $k$ 个基础函数,形成长度为 $k$ 的完整复合键 $$ K j(x)=(h {j,0}(x),\ldots,h {j,k 1}(…”
形式陈述
哈希表用函数
令存储的不同键数为
插入新键前若需检查并覆盖同键旧值,也要承担这次查找;按键删除同样如此。已经持有合法节点句柄的局部插删可以更便宜,但不能把它们的成本冒充按键操作。某个固定函数仍可能把全部键放进同一桶,故没有无条件的最坏常数查询保证。
直觉
哈希表先把搜索范围缩到一个桶,再用键相等判断识别真正目标。数组访问解决的是“去哪一桶”,碰撞策略解决的是“桶里不止一项怎么办”。期望常数时间来自负载和随机性条件,两者都不是使用数组后自动获得的性质。
这也解释为何哈希表通常不提供键的排序次序。两个相近键可能进入很远的槽,两个无关键也可能碰撞;桶下标不是业务上的大小关系。需要前驱、后继或范围查询时,应比较有序搜索结构的接口。
例子与边界
同一组碰撞,不同处理方法
取容量
若在线性探测中删除槽
期望界怎样得到
对固定查询键
再加定位桶和检查目标的常数工作,就得到链地址法的
开放定址的探测长度依赖整个探测序列,不能仅凭首页碰撞概率沿用上述证明。装载率接近
推论与应用
扩容、重哈希与字典语义
扩容后桶下标通常改变,必须把有效键重新放置。对链地址表,若保持常数负载、采用几何容量变化及分离的扩缩阈值,并能在线性时间内搬迁记录,摊还分析把偶发重建分散到一串更新上;普通按键查找的随机成本仍需另计,合起来常得到期望摊还常数更新。某次重建依然可能是线性的。
跨服务器选择负责位置时,一致性哈希环固定token边界,使加入只切分一段、删除只移交原负责段;Rendezvous哈希则为每把键给节点稳定排名,成员变化不改变幸存节点之间的相对次序。两者解决跨节点放置,不替代本页的节点内碰撞解析,也不证明新目标已经收到数据。
页式动态哈希可避免每次增长都搬整张记录表:可扩展哈希用目录别名及局部深度拆热点桶,目录翻倍的指针复制仍需单独计费;线性哈希按固定分裂指针逐桶扩展,但发生溢出的桶可能暂时继续保留长链。两者维持精确字典语义,不因此获得与分布无关的最坏常数访问。
哈希表、搜索树和 trie 可以在不同键域条件下实现字典、映射与集合 ADT。选择结构时,应先固定精确查询、覆盖更新、删除和迭代契约,再分别比较最坏、期望与摊还成本。
开放定址把记录放在表槽内;Cuckoo Hashing再限制每键的候选位置,并允许插入时搬走旧键;完美哈希则针对静态集合构造无冲突的查询表示。它们使用不同的冲突约束和构造保证。
Bloom Filter只提供可能带假阳性的成员测试,不保存值,也不实现这里的精确字典。密码学哈希的抗碰撞目标同样不同于桶分布和查询时间,不能把这些保证统称为“哈希性能”。
配套实验
字典契约实验把同一条含碰撞、更新和删除的历史交给链地址表与线性探测表,逐步比较抽象映射,并分别记录键比较、探测和重建工作。其固定取模哈希用于复算正确性,不是上述随机期望界的性能实验。
参考资料
- Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022,Chapter 11:链地址、哈希函数与开放定址。
- Robert Sedgewick、Kevin Wayne,Algorithms, 4th ed., Addison-Wesley, 2011,§3.4:哈希符号表。
- J. Lawrence Carter、Mark N. Wegman,“Universal Classes of Hash Functions”,Journal of Computer and System Sciences 18(2), 1979,pp. 143–154。