当前位置: 首页 > 知识库问答 >
问题:

为什么二次探测不能找到下一个插入的位置,而线性探测总是找到一个?

葛承嗣
2023-03-14

问题

根据答案键(来自链接),1的答案是i,2的答案是ii。

我同意问题1的答案。线性探测将探索所有可能性,如果需要,将其包装到哈希表的开头。因此,它将在下一次插入时找到一个位置。如果插入一组映射到同一个bucket或一个bucket附近的值,将导致集群,性能将降低
我理解为什么问题2的答案不是I。二次增量通过不同的增量进行探测,以避免聚类问题。然而,一些人能解释二次探测“在下一次插入时可能找不到位置”背后的直觉吗?
二次探测函数定义为(从二次探测开始)
n次探测为((h(k)n2)mod TableSize),直到探测到达零(未占用)

从我在另一个问题“二次探测”中学到的知识来看,二次探测有可能击中每一个桶。与线性探针一样,如果需要,二次探针也应该包装到哈希表的开头。那么,在这个问题中,为什么二次探头不能在下一次插入时找到位置,而线性探头可以?

共有3个答案

越风史
2023-03-14

一定有证据证明这一点。但是,我不明白在大多数情况下,二次探测怎么可能击中每一个桶。

假设桌子的大小是7,h(k)是0。对于第i次迭代,probe=i^2 mod 7。我测试了所有小于10000的I,对于任何I,它的计算结果总是为0、1、2或4。桶3、5和6永远不会被探测。

以下是我使用的脚本:

var hash_of_k = 0;
var table_size = 7;
var iteration_limit = 10000;
var buckets =  new Object();

//Probe buckets
for(var i=0; i<iteration_limit; i++){
  b = (hash_of_k+(i*i)) % table_size;
  buckets[b] = 1;
}

//Report which buckets were probed.
var buckets_probed = '';
for(b in buckets){
  buckets_probed += b + '  ';
}

alert(buckets_probed);
白学
2023-03-14

我认为问题是在什么情况下,二次探测根本无法找到下一个位置,以防发生碰撞。

在下面的例子中,我确实看到二次探测在与相同的结果键发生碰撞时无法找到位置。

假设哈希表大小为7。

下面是要插入23, 39, 9, 16, 30数字。

h(k,i)=[h(k)sqr(i)]模式7,其中h(k)=k模式7。

for i = 0, h(k,0) = h(k)
for i = 1, h(k,1) = [h(k) + 1] mod 7
for i = 2, h(k,2) = [h(k) + 4] mod 7
for i = 3, h(k,3) = [h(k) + 9] mod 7

23 --> 23 % 7 = 2

39 --> 39 % 7 = 4

9  --> 9 % 7 = 2 <--- Collision
   2 + 1 = 3

16 --> 16 % 7 = 2 <--- Collision
   2 + 1 = 3 <--- Collision
   2 + 4 = 6

30 --> 30 % 7 = 2 <--- Collision

   2 + 1 = 3 <--- Collision

   2 + 4 = 6 <--- Collision
   2 + 9 = 4 <--- Collision
   2 + 16 = 4 <--- Collision
   2 + 25 = 6 <--- Collision
   2 + 36 = 3 <--- Collision
   2 + 49 = 2 <--- Collision
   2 + 64 = 3 <--- Collision
   2 + 81 = 6 <--- Collision
   2 + 100 = 4 <--- Collision
   2 + 121 = 4 <--- Collision
   2 + 144 = 6 <--- Collision
   2 + 169 = 3 <--- Collision
   2 + 196 = 2 <--- Collision
   2 + 225 = 3 <--- Collision
   2 + 256 = 6 <--- Collision
   2 + 289 = 4 <--- Collision
   2 + 324 = 4 <--- Collision
   2 + 361 = 6 <--- Collision
   2 + 400 = 3 <--- Collision

任何键k(k mod size)等于2(如37、44、51、58等)都会出现这种情况。

冯枫涟
2023-03-14

为了找出h(k)n^2是否搜索所有可能性,您需要找出n^2是否占用了所有可能的值,例如哈希表大小。所以您需要知道通过选择n的所有N个可能性,是否可以让n^2占用所有N个可能的不同值。

(-n)^2=n^2,所以这里是平方函数的不同输入值,它们产生相同的输出值。因此,不可能产生所有N个不同的输出值,因为不同输入值的结果之间存在冲突。

示例-工作模式7. 1^2 = 6^2 = 1. 2^2 = 5^2 = 4. 3^2 = 4^2 = 2. 7^2 = 0。因此,如果您将输入平方(0, 1, 2, 3, 4, 5, 6)您将获得输出(0, 1, 4, 2, 2, 4, 1)并且您不能产生3、5或6-事实上,这个示例足以表明您不能保证搜索所有可能的插槽,但上面的数学足够简洁,比我的算术更可靠,并表明这里的行为非常一般。

 类似资料:
  • 我在研究hackerearth上的哈希表,在那里我遇到了用线性探测实现哈希表的代码。我对这段代码有两个疑问:- 1)为什么他们声明大小为21(而不是大小为20)的hashTable最多容纳20个元素? 2) 在Insert函数中,当循环无限运行时,如果在连续迭代之后,索引的值变为索引的初始值,不是吗? 链接至黑客主页:-https://www.hackerearth.com/practice/da

  • 这是一个类似于线性探测运行时的问题,但它涉及二次探测。 对我来说,“理论上最坏的情况是O(n)”对于线性探测是有意义的,因为在最坏的情况下,你可能需要遍历每个桶(n个桶) 二次探测的运行时是什么?我知道二次探测-1, 4, 9, 16,......我最初的想法是这是对数n(指数)的一些变化,但没有一致的基数。

  • 我正在用一个字符串数组单维和一个2维int数组制作哈希表。我正在使用线性探测进行冲突检测,当我意识到如果检测到冲突,单词的hashCode将不再是索引时,我真的很兴奋地完成了这个程序。我该如何保存该索引以备以后使用?

  • 这段代码(从来历不明的LZW压缩程序中提取)在大小为5021的哈希表中找到一个空槽,索引从0到5020: 这不是典型的线性或二次探测。为什么要这样调查?这是一种已知的探测算法吗?我在哪里可以找到更多关于它的信息?

  • 以下是我对线性探测的理解。 对于插入:-我们散列到某个位置。如果该位置已经有一个值,我们线性增加到下一个位置,直到我们遇到一个空位置,然后我们在那里插入。这是有意义的。 我的问题围绕着查找。从我读过的描述中,我相信查找是这样工作的: 我们查看要查找散列的项的位置 那么,当我们从散列中删除一项时,这是如何工作的呢?这不会把查找搞砸吗?假设两个项目散列到同一位置。我们添加两个项目,然后删除我们添加的第

  • 我在做一个程序,比较哈希表中线性探测、二次探测和单独链接所需的平均访问量和最大访问量。 我已经做了三个案例的元素插入部分。当从哈希表中找到元素时,我需要有一个结束搜索的限制。在单独链接的情况下,当下一个指针为空时,我可以停止。对于线性探测,当探测到整个表时,我可以停止(即表的大小)。在二次探测中,我应该用什么作为限制?表大小可以吗? 我的二次探测函数是这样的 其中i从0到无穷大。请帮帮我...