当你在双散列中与主散列函数发生冲突时,你使用辅助散列函数。但是如果你也与它发生冲突,那么你必须重新散列,所以你将表大小加倍,并选择最近的素数作为新表大小。这也会改变你的主散列函数吗?例如,如果你的主散列函数是key mod tableSize,你的tableSize最初是11,现在是23,那么这也会改变吗?因为如果散列函数保持不变,你仍然会在相同的位置发生冲突。
当您在双散列中与主散列函数发生冲突时,您使用辅助散列函数。但是如果您也与之发生冲突,那么您必须重新散列,因此您将表大小加倍并选择最近的素数作为新表大小。
我不认为这是真的。
在双重散列中,
h(k,i) = h1(k) + i*h2(k)
其中h(k, i)是探测到键的第(i)个插槽。所以你连续增加i,这样你就命中了一个空插槽。
您需要重新散列,当负载因子超过特定值时,是的,当重新散列时,主散列函数通常会发生变化,但我认为您可以不使用它([编辑:更改主散列函数]),尽管它会降低性能。
实际上,对于双重散列,我使用表大小2^N和两个散列函数,计算值h1(位置)和h2(步骤)。步长必须是奇数,对于符合条件
gcd(table_sz, step) == 1
满足此条件后,试用期索引迭代表中的所有单元格。
此后,我只是用索引(pos)、(pos step)、(pos step step)等迭代表,以table_size取模。
程序的主循环看起来像:
do {
pos = (pos + step) & (TAB_SIZE - 1);
} while(table[pos] have collision);
在此处查看简单的实现示例:
http://olegh.cc.st/src/words.c.txt
有趣的实现,当您有TAB_SIZE=2^16时。在这种情况下,您可以将变量(pos, step)定义为无符号短,并且不需要应用掩码(TAB_SIZE-1);相反,您只需编写:
pos += step;
几周前在我的数据结构课上,我们正在研究哈希表。我也遇到了这种困境。当我问我的教授时,他说没有必要在重新散列时更改主散列函数。即使从技术上讲,你仍然可以在相同的地方发生碰撞,但使用开放寻址技术重新散列时仍然可以找到一个空点。然而,他说通常主散列函数会被更改为新的模,原因之一是它有助于防止数据聚类。综上所述,从他所说的来看,无论哪种方式都没有对错,但是改变哈希函数是更好的方法,以避免在相同的地方聚类和碰撞。希望这有帮助!