Cuckoo Hashing (布谷鸟散列)

本文深入探讨了CuckooHashing的基本原理,包括使用两个哈希表和两个哈希函数实现快速查询与删除。插入操作可能导致的死循环问题通过设定循环阈值来解决,并介绍了CuckooGraph作为辅助分析工具。文章还提出了关于插入成功的定理,并分析了插入操作的最坏情况。此外,通过CuckooGraph展示了插入过程中的边移动,揭示了插入失败的条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


本文主要对 Cuckoo Hashing (布谷鸟散列) 的基本原理进行描述

原理

综述

  1. 维护两个表 T 1 , T 2 T_1,T_2 T1,T2,每个表都有 m m m 个元素
  2. 选择两个哈希函数 h 1 h_1 h1 h 2 h_2 h2,这两个哈希函数将输入空间 Ω \Omega Ω 映射到 0 ∼ m − 1 0\sim m-1 0m1
  3. 对于元素 x ∈ Ω x\in \Omega xΩ x x x 要么存储在 T 1 T_1 T1 的位置 h 1 ( x ) h_1(x) h1(x) 处,要么存储在 T 2 T_2 T2 的位置 h 2 ( x ) h_2(x) h2(x)

在这里插入图片描述

查询&删除

Cuckoo Hashing 查询操作时间复杂度为 O ( 1 ) O(1) O(1),因为每个元素只可能存储在两个位置

Cuckoo Hashing 删除操作时间复杂度为 O ( 1 ) O(1) O(1),因为每个元素只可能存储在两个位置

插入

  1. 为了插入一个元素 x x x,将其插入到 T 1 T_1 T1
  2. 如果 T 1 T_1 T1 的位置 h 1 ( x ) h_1(x) h1(x) 处是空的,那就把 x x x 插入到该位置即可
  3. 如果 T 1 T_1 T1 的位置 h 1 ( x ) h_1(x) h1(x) 已经被元素 y y y 占用了,那就牺牲掉 y y y,把 x x x 插入到该位置,然后再尝试把 y y y 插入到 T 2 T_2 T2 的位置 h 2 ( y ) h_2(y) h2(y)
  4. 类似地,如果 T 2 T_2 T2 的位置 h 2 ( y ) h_2(y) h2(y) 处是空的,就把 y y y 插入到该位置即可;如果 T 2 T_2 T2 的位置 h 2 ( y ) h_2(y) h2(y) 处已经被元素 z z z 占用了,先把 y y y 插入到该位置,然后尝试把 z z z 插入到 T 1 T_1 T1 的位置 h 1 ( z ) h_1(z) h1(z) 处。依此类推,直到所有的元素都插入成功了。
  1. 插入操作可能会陷入死循环,比如考虑三个元素 A ,B和C, h 1 ( A ) = 0 , h 2 ( A ) = 1 , h 1 ( B ) = 0 , h 2 ( B ) = 1 , h 1 ( C ) = 0 , h 2 ( C ) = 1 h_1(A)=0,h_2(A)=1,h_1(B)=0,h_2(B)=1,h_1(C)=0,h_2(C)=1 h1(A)=0,h2(A)=1,h1(B)=0,h2(B)=1,h1(C)=0,h2(C)=1,假设 A 已经存储在 T 1 T_1 T1 的位置0处了,B 已经存储在 T 2 T_2 T2 的位置1处了,现在要插入 C,首先 C 会插入 T 1 T_1 T1 的位置0处,然后 A 被牺牲,因此 A 插入 T 2 T_2 T2 的位置1处,然后 B 被牺牲,因此接下来会将 B 插入 T 1 T_1 T1 的位置0处,此时 C 被牺牲,然后 C 会被插入 T 2 T_2 T2 的位置1处,依此往复,陷入死循环
  2. 为了解决该问题,可以考虑设置一个阈值,当循环的次数大于该次数时,认为此时发生了死循环,此时选择新的 h 1 h_1 h1 h 2 h_2 h2,然后将所有的元素通过使用这两个新的哈希函数重新插入表中
  3. Cuckoo Hashing之所以这样命名,是因为上述插入如果发生冲突,其处理该冲突的过程类似于:布谷鸟不自己筑巢,而是在别的鸟巢里面孵化鸟蛋,孵化出的幼鸟会将别的鸟蛋挤出

Cuckoo Graph

简介

为了方便研究Cuckoo Hashing,尤其是上面的插入操作,引入Cuckoo graph

Cuckoo graph 是从哈希表导出的二部图,下图为一个实例

在这里插入图片描述

每条边上有一个元素,可以理解为每条边代表一个元素,该边连接了该元素在两个表中可能存放的位置;每次插入一个元素会往其中引入一条边

一个插入操作会经历cuckoo graph中的一系列边,下面考虑两个实际的例子

  1. 往其中插入88,首先引入一个边,该边连接了88在两个表中可能的位置,如下图所示,下图中标蓝路径是插入88后,各个元素不断移动位置所经历的边,如果不明白这个意思,建议复现一下插入88的完整过程,这样就可以理解了

    在这里插入图片描述

  2. 接下来往其中插入4,首先引入一个边,该边连接了4在两个表中可能的位置,如下图所示,该插入操作会导致死循环,下图红色路径显示了各个元素不断移动位置所经历的边

    在这里插入图片描述

定理

定理1:将 x 插入到 Cuckoo 哈希表中,如果包含 x 的连通分量有两个或更多循环,则插入失败。

证明:cuckoo graph中每条边可以代表一个元素,每个节点代表哈希表中的一个位置

如果在该连通分量中有k个节点,由于该连通分量至少有2个循环,因此边的个数至少为k+1,k+1个元素(边)不可能放入k个位置(节点)中,因此插入失败

定理2:如果 x 被插入到一个 cuckoo 哈希表中,如果包含 x 的连通分量不包含循环或只有一个循环,则插入成功

定理3:如果将 x 插入到具有 k 个节点的连通分量中,则插入过程最多进行 2k 次位移。

术语:

  1. A tree is an undirected, connected component with no cycles.
  2. A unicyclic component is a connected component with exactly one cycle.
  3. A connected component is called complex if it’s neither a tree nor unicyclic.

定理4:Cuckoo hashing fails iff any of the connected components in the cuckoo graph are complex.

To analyze cuckoo hashing, we’ll do the following.

  1. First, we’ll analyze the probability that a connected component is complex.
  2. Next, under the assumption that no connected component is complex, we’ll analyze the expected cost of an insertion.
  3. Finally, we’ll put the two together to complete the analysis
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值