摘要
在本文中,我们重新审视数据结构中最简单的问题之一:插入的任务元素进入开放式哈希表中,以便以后可以检索元素尽可能探针。我们表明,即使没有随着时间的推移重新排序元素,也可以构建一张哈希表,可以实现更好的预期搜索复杂性(均被摊销和最糟糕的案例)比以前认为的。一路走来,我们在他的开创性论文“统一哈希是最佳的”中,反驳了Yao留下的中央骗局。我们所有的结果都来了与匹配的下限。
论文的背景是开放寻址哈希表的基本问题:插入元素时,如何通过探测序列找到未占用的位置,并最小化搜索的探测次数。传统的均匀探测(uniform probing)方法虽然被广泛使用,但其在预期探测次数上有一定的限制,例如在负载因子较高时,预期探测次数会显著增加。
论文的主要贡献在于提出了两种新的哈希表构造方法:弹性哈希(Elastic Hashing)和漏斗哈希(Funnel Hashing)。弹性哈希通过非贪婪的探测策略,允许在插入时多次探测不同的子数组,从而在平均情况下实现O(1)的预期探测复杂度,同时在最坏情况下保持O(log δ⁻¹)的复杂度。漏斗哈希则是一种贪婪方法,通过多层子数组结构和双选择策略,在最坏情况下达到O(log² δ⁻¹)的预期探测复杂度,同时在高概率下保持较低的探测次数。
方法
1.弹性哈希(Elastic Hashing)
关键公式:
-
核心思想:通过非贪婪的探测策略,允许插入时多次探测不同子数组,优先尝试低负载子数组,若失败再转向高负载子数组。
-
实现步骤:
-
将哈希表分割为多个几何递减大小的子数组(如
)。
-
每个元素的探测序列按优先级从低负载子数组开始,若失败则逐步转向高负载子数组。
-
插入时通过多级探测序列(如
)动态选择插入位置。
-
其中,将二维探测序列映射为一维度的注入函数。
2.漏斗哈希(Funnel Hashing)
-
核心思想:通过多层子数组结构和双选择策略,结合均匀探测与负载均衡,优化最坏情况下的探测复杂度。
-
实现步骤:
-
哈希表分为主数组 A′A′ 和特殊数组 Aα+1Aα+1,主数组进一步划分为多个子数组 AiAi。
-
插入时依次尝试各子数组,若均失败则使用特殊数组(基于双选择策略)。
-
特殊数组采用两阶段插入:先尝试均匀探测,失败后使用双选择桶(Bucket)结构。
-
-
关键公式:
其中m为插入元素数,n为桶数量,保证高概率下桶不溢出。
原理
-
避免“优惠券收集”瓶颈
-
传统均匀探测需收集足够多的“优惠券”(即探测次数),导致预期探测复杂度为 O(logδ−1)。
-
弹性哈希通过将插入探测复杂度与搜索探测复杂度解耦,使得大部分探测仅影响插入时间,不影响搜索效率。
-
-
动态负载均衡
-
弹性哈希通过子数组分割和探测优先级调整,将高负载插入分散到多个子数组,减少单次插入的探测压力。
-
漏斗哈希通过多层子数组和双选择策略,确保即使某一层负载较高,其他层仍能保持低探测复杂度。
-
-
概率分析与下界证明
-
使用 Chernoff 不等式 和 McDiarmid 不等式 分析探测次数的集中性与期望值。
-
证明任何非重排开放寻址哈希表的最坏情况探测复杂度下界为 Ω(logδ−1),漏斗哈希的最坏情况复杂度下界为 Ω(log2δ−1+loglogn)。
-
创新点: