蝉的哲学
蝉的生命周期为13年或17年,却很少有14、15或16年,为什么呢?蝉是弱势群体,有很多天敌,选择素数作为其生命周期能最大减少与其天敌们共存的时间,增加自己的存活率,这也是自然选择的结果。
原理分析
从蝉的哲学中获得启示,将哈希取余的基底选择为素数能最大减少哈希冲突情况的发生,使哈希分布更均匀。
假设hash(key) = key % M,
若 M = 2k, 则 key % M = key & (M - 1), 而
M - 1 = 00000…(n-k个0)…000000 1111…(k个1)…11111
key跟M - 1相与之后,永远只截取了最后k位,前n - k位对哈希地址无影响,显然这样会增加哈希冲突的概率。
M取其他非素数仍然会有类似的缺陷,只有当M为素数时,数据对散列表的覆盖最充分、分布最均匀。
为什么M取素数时覆盖最均匀?
我们处理的数据一般都具有局部性,通常像for或while循环一样以一定的步长遍历数据,遍历方式如下所示:
由数论的知识可以知道当且仅当步长S与M的最大公因数为1时,遍历的足迹才能覆盖整个散列表。不同的程序代码有不同的步长遍历方式,他们可能都要使用同一个散列表,当M为素数时才能保证M与所有的步长S的最大公因数都为1。即M取素数时才能使遍历的足迹分布均匀,减少冲突发生的概率。