散列表长度和素数的关系
来源:互联网 发布:mac如何截取视频片段 编辑:程序博客网 时间:2024/05/17 03:08
看到很多散列表(hash table)的实现中,长度都是一个素数。至于为什么一定要用素数,一下子也没想出所以然来。上网搜索了一下相关的文章,发现很多人也在讨论这个问题。
http://www.cs.unm.edu/~saia/numtheory.html
http://www.codexon.com/posts/hash-functions-the-modulo-prime-myth
http://www.codexon.com/posts/hash-functions-the-modulo-prime-myth-2
http://blog.csdn.net/ilibaba/archive/2009/03/05/3960142.aspx
长度是否要是素数,能不能是合数,这个问题大家的意见得不到统一。支持用素数的人的理由是,素数可以使得散列的分布更加均匀。
自己总结一下看这些文章的心得。一个散列运算可以等价如下式:
hash(k) = mix(k) mod m
散列计算中,求余往往是最后一步,因为没有机器拥有无限的内存,所以必须把结果放入到有限的桶(bucket)中。求余前的运算,假如混淆(mix)得比较好的话,那么m使用素数还是合数,分布是一样的。假如混淆(mix)得不够好的话,那么一个素数可以把一些common pattern加以区别。至于什么样的数据混淆用什么样的mix算法比较好,这个得经统计才可以得出结论。总的来讲,使用一个素数总没有错,虽然运行慢了点,却可以得到相对较好的统计特性。个人看法。
Knuth的The Art of Computer Programming中,也用的是一样的理由推荐用素数的m。手上没有书,他应该没有提到合数的问题。上面也仅仅是我个人的一些想法,没有经过严格的证明,我也没有能力去证明。当然,很欢迎有人来指正我的错误。
手上有《算法导论》,第十一章散列表,对这个问题也没有给出严格的证明。但是它提到这样的一个问题,若m=2^p-1,则所有以2^p为基数的解释的字符串,无论字符位置怎么变化,得出的散列值都是一样的。这个证明比较简单,用同余的性质就可以证明,最后的值,其实是各个字符值的和再对m取余,所以散列值不会随字符的位置发生变化。
UPDATE:
StackOverflow上也有对这个问题的讨论。
http://stackoverflow.com/questions/1145217/why-should-hash-functions-use-a-prime-number-modulus
上面的文章的观点和我总结出来的基本一致。
from http://hi.baidu.com/vwin044/item/374ee83d11aad5d02784f4c0
- 散列表长度和素数的关系
- 天线的长度和波长的关系
- 天线长度和频率的关系
- 动态改变CComboBox的下拉列表的长度和宽度
- 改变下拉列表的长度
- 实际参数列表和形式参数列表长度不同的问题
- 初始化列表和声明的顺序之间的关系
- hdoj 2521 反素数(水!和素数没半毛钱关系)
- DPI和像素、厘米、英寸之间的关系和换算及CSS中的长度单位
- 错误: 实际参数列表和形式参数列表长度不同
- 2-50之间的素数列表
- 返回100内的素数列表
- Python中如何使用*args 和 **kwargs (非keyworded,可变长度参数列表 keyworded形式可变长度的参数列表)
- 如何得到贝塞尔曲线的曲线长度和 t 的近似关系?
- 设定select下拉列表的长度
- 求闭散列表的平均查找长度
- P04(*) 获取列表的长度【重补】
- int的长度跟编译器有关系
- 精装友情通讯录算法逆向与注册机实现
- 学习spring对于单态模式和工厂模式的实现
- 为什么shell的变量定义不能有空格
- 如何避免危险的免费wifi?
- 使用stringstream对象简化类型转换
- 散列表长度和素数的关系
- 亚马逊正式发布Fire Phone 合同价199美元起
- Unable to locate package错误解决办法
- 为什么要使用git,怎么用?
- 子线程中更新ui界面
- 二次开发遇到的问题
- libevent 杂项篇--最小堆miniheap
- get请求和post请求的区别
- android仿IOS页面回弹效果