在构建散列表时,最常用的散列函数之一是除法散列函数,本文简单描述为什么除法散列函数取余时要模素数。
除法散列函数的形式如下: 对于一个散列函数,其目的是将一个大的空间尽量均匀地映射到一个小的空间。那么对于上述形式的除法散列函数,我们想要的效果是对于任意的输入集合 ,其映射尽量均匀地分布在集合 上。
容易想到,如果集合 本身就是均匀分布的,类似于集合 ,那么 的取值是无所谓的,集合 总能被均匀映射到集合 。但是,现实世界的输入往往不是如此,比如集合 中可能大多数是偶数,那么最后的映射结果就会不均匀。
那么为什么取 为素数可以解决这个问题呢?
我们可以假设 不是素数,那么也就存在 ,在 , 时有 ,其中 是 和 的最大公约数。
设 ,那么就有 ,其中 是 整除以 的结果。
因此我们就有: 代入得到: 因为 ,所以可以得到: 容易看出, 和 都是整数,那么 也一定是整数,也就是说,此时 的分布空间为 ,是我们期望分布空间的 。那么只要取 我们就可以保证映射结果的均匀,即 要为素数。
参考文献
- Hash时取模一定要模质数吗? - 我只想做一只懒猫的回答 - 知乎 https://www.zhihu.com/question/20806796/answer/159392465