散列函数中求模运算为什么要使用素数,原因分析

一、散列函数

散列函数即是将元素映射到对应槽位置的方法。

一个好的散列函数应该是尽可能的将元素均匀的散列到 m 个槽位中的一个。

 

二、除法散列法

散列函数的实现有很多种,其中一种常见的散列函数即 除法散列法,h(k) = k mod m,通过取 k 除以 m 的余数,将关键字 k 映射到 m 个槽上。由于只需做一次除法操作,所以除法散列法是非常快的。

当我们使用除法散列法时,m 的选择很重要。《算法导论》一书中,建议我们使用一个不太接近 2 的整数幂的素数,作为 m 的选择。

那么在求模运算中为什么建议要使用素数呢?这是因为使用素数可以让元素取模后的值,更不容易发生冲撞。至于是为什么,我们在下面探讨。

 

三、对素数取模的好处

前面说道,对素数取模,结果更不容易发生冲撞,即结果可以更均匀的散列到不同的槽位中。那么原理是怎么样的呢?

合数和素数:合数即有两个以上的因数,素数(质数)即只有两个因数,分别为 1 和其本身。

如果对一个合数取模,那么对其某个因数取模,结果可能仍然一致。例如 10 对 8 取模,结果为 2,对 4 取模,结果也为 2。而我们对一个素数取模,由于素数只有 1 和其本身两个素数,即不可能出现上述情形。

 

四、实例分析

1. 数列A:1,3,5,7,9,11,13,15

假设选取 8 取模,结果为:

余数01234567
数值 1 3 5 7
数值 9 11 13 15

每个数间隔 2,2 是 8 的一个因数,容易发生冲突,不均匀分布。

假设选取 7 取模,结果为:

余数0123456
数值719311513
数值 15     

每个数间隔 2,2 不是 7 的因数,均匀分布。

 

2. 数列B:2,5,8,11,14,17,20,23

假设选取 8 取模,结果为:

余数01234567
数值817211205147
数值       23

每个数间隔 3,3 不是 8 的因数,均匀分布。

假设选取 7 取模,结果为:

余数0123456
数值14821711520
数值  23    

每个数间隔 3,3 不是 7 的因数,均匀分布。

 

3. 总结

如果数列的间隔为 1,那么不管模数为几都会均匀分布。

如果间隔是模数的因数,则容易发生冲突,且模数的因数越多,冲突的可能性越大。

素数只有两个因数,所以可以保证发生冲突的可能性最小。

  • 14
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值