【问题标题】:Quadratic testing in hash tables哈希表中的二次测试
【发布时间】:2010-01-03 09:22:22
【问题描述】:

在作业期间,我被要求展示一个大小为 m(m>3,m 是素数)的哈希表,它小于半满,并且使用二次检查 (hash(k, i) = (h(k) + i^2) mod m),我们总能找到空位。

我已经检查并得出结论,将找到的点(当 h(k)=0 时)是 0 mod m1 mod m4 mod m9 mod m、...
我的问题是我想不出一种方法来证明它总能找到空闲位置。我自己用不同的 m 值对其进行了测试,并且也证明了自己如果哈希表超过半满,我们可能永远找不到空闲位置。

谁能提示我解决这个问题的方法?

谢谢!

【问题讨论】:

    标签: algorithm hash hashtable


    【解决方案1】:

    0, 1, 4, ..., ((m-1)/2)^2 都是不同的 mod m。为什么?

    假设该范围内的两个数 i^2 和 j^2 等价于 mod m。

    那么 i^2 - j^2 = (i-j)(i+j) = 0 (mod m)。由于 m 是素数,因此 m 必须除以其中一个因数。但因数都小于m,所以其中一个((i-j))为0。即i = j。

    由于我们从 0 开始,因此有一半以上的插槽是不同的。如果您只能填充少于 m/2 的它们,则至少有一个保持打开状态。

    【讨论】:

      【解决方案2】:

      让我们分解证明。


      设置

      首先,一些背景。

      • 使用哈希表,我们定义了一个探测序列P。对于任何项目q,跟随P 最终将导致哈希表中正确的项目。探测序列只是一系列函数{h_0, ..., h_M-1},其中h_i 是一个哈希函数。

      • 要将项目q 插入表中,我们查看h_0(q)h_1(q) 等,直到找到一个空位。为了稍后找到q,我们检查了相同的位置序列。

      一般来说,探测序列的形式为h_i(q) = [h(q) + c(i)] mod M,用于大小为M 的哈希表,其中M 是质数。函数c(i)是冲突解决策略,它必须有两个属性:

      首先,c(0) = 0。这意味着序列中的第一个探测必须等于只执行哈希。

      其次,{c(0) mod M, ..., c(M-1) mod M} 的值必须包含 0 到 M-1 之间的每个整数。这意味着如果你不断尝试寻找空点,探测序列最终会探测到每个阵列位置。


      应用二次探测

      好的,我们已经设置了哈希表的工作原理。让我们看看二次探测。这只是意味着对于我们的c(i),我们使用ai^2 + bi + c 形式的一般二次方程,尽管对于大多数实现,您通常只会看到c(i) = i^2(即b, c = 0)。

      二次探测是否满足我们之前谈到的两个性质?嗯,这里c(0) = 0 肯定是真的,因为(0)^2 确实是0,所以它满足第一个属性。第二个属性呢?

      事实证明,总的来说,答案是否定的。

      定理。 当在大小为M 的哈希表中使用二次探测时,其中M 是质数,只有探测序列中的第一个floor[M/2] 探测是不同的。

      让我们看看为什么会这样,使用反证法。

      1. 说这个定理是错误的。那么这意味着有两个值ab 使得0 <= a < b < floor[M/2] 探测相同的位置。

      2. h_a(q)h_b(q) 必须探测相同的位置,通过 (1),所以 h_a(q) = h_b(q)

      3. h_a(q) = h_b(q) ==> h(q) + c(a) = h(q) + c(b), mod M.

      4. 两边的h(q)取消。我们的c(i) 只是c(i) = i^2,所以我们有a^2 = b^2

      5. 求解 (4) 中的二次方程得到 a^2 - b^2 = 0,mod M。这是 difference of two squares,所以解是 (a - b)(a + b) = 0mod M

      6. 但请记住,我们说M 是质数。 (a - b)(a + b) 可以为零 mod M 的唯一方法是 [case I] (a - b) 为零,或 [case II] (a + b ) 为零mod M

      7. 我不可能是对的,因为我们说a != b,所以a - b 必须不是零。

      8. (a + b) 为零mod M 的唯一方法是a + b 等于M 的倍数或零。它们显然不能为零,因为它们都大于零。由于它们都小于floor[M/2],因此它们的总和必须小于M。所以情况二也不对。

      因此,如果定理是错误的,则两个量中的一个必须为零,而这两个量都不可能为零——矛盾! QED:一旦你的表超过一半并且你的表大小是质数,二次探测就不能满足属性二。证明完毕!

      【讨论】:

      • 这个证明是否只适用于f(i) = i^2的情况;或者,它是否可以推广到任何二次方程?乍一看,在我看来,如果存在一个线性术语(例如,f(i) = a*i + b*i^2)将允许在 M/2 之前重复
      【解决方案3】:

      来自Wikipedia

      对于素数 m > 2,c1 和 c2 的大多数选择将使 h(k,i) 对于 [0,(m − 1) / 2] 中的 i 是不同的。此类选择包括 c1 = c2 = 1/2、c1 = c2 = 1 和 c1 = 0,c2 = 1。因为给定元素只有大约 m/2 个不同的探针,所以它是当负载因子> 1/2时,很难保证插入会成功。

      请参阅Data Structures and Algorithms with Object-Oriented Design Patterns in C++ 中的二次探测部分,以证明当 m 为素数时 m/2 个元素是不同的。

      【讨论】:

      • 谢谢!如果我知道它在英语中被称为“探测”而不是“测试”...... :)
      • 不幸的是,引用的证明不是因为 m 是质数部分,而是因为 m 是 2 部分的幂。
      猜你喜欢
      • 2012-08-20
      • 1970-01-01
      • 2013-04-06
      • 2016-03-09
      • 2014-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      相关资源
      最近更新 更多