解析哈希表中数组的容量为什么是质数
2015-01-23 14:37
267 查看
HASH函数需要把原始数据均匀地分布到HASH数组里,比如大部分是偶数,这时候如果HASH数组容量是偶数,容易使原始数据HASH后不会均匀分布:
2 4 6 8 10 12这6个数,如果对 6 取余 得到 2 4 0 2 4 0 只会得到3种HASH值,冲突会很多。如果对 7 取余 得到 2 4 6 1 3 5 得到6种HASH值,没有冲突。
同样地,如果数据都是3的倍数,而HASH数组容量是3的倍数,HASH后也容易有冲突,用一个质数则会减少冲突的概率,更分散。
以下是求质数的代码:
再哈希法要求表的容量是一个质数。为什么会有这个限制,假设表的容量不是质数,表长是15(坐标 0 - 14),有一个特别关键字映射到0,步长为5,探测序列为0、5、10、0、5……,一直循环下去,算法只会尝试这三个单元,不可能找到其它空白单元,算法崩溃。
如果数组容量是13,即一个质数,那么探测序列会访问到所有单元。即0、5、10、2、7、12、4、9、1、6、11、3,一直下去,只要表中有一个空位,就可以探测到它。用质数作为数组容量使得任何数想整除它是不可能的,因此探测序列最终会检查到所有单元。
2 4 6 8 10 12这6个数,如果对 6 取余 得到 2 4 0 2 4 0 只会得到3种HASH值,冲突会很多。如果对 7 取余 得到 2 4 6 1 3 5 得到6种HASH值,没有冲突。
同样地,如果数据都是3的倍数,而HASH数组容量是3的倍数,HASH后也容易有冲突,用一个质数则会减少冲突的概率,更分散。
以下是求质数的代码:
private int getPrime(int min) { for (int j = min;; j++) { if (isPrime(j)) { return j; } } } private boolean isPrime(int num) { for (int j = 2; j * j <= num; j++) { if (num % j == 0) { return false; } } return true; }
再哈希法要求表的容量是一个质数。为什么会有这个限制,假设表的容量不是质数,表长是15(坐标 0 - 14),有一个特别关键字映射到0,步长为5,探测序列为0、5、10、0、5……,一直循环下去,算法只会尝试这三个单元,不可能找到其它空白单元,算法崩溃。
如果数组容量是13,即一个质数,那么探测序列会访问到所有单元。即0、5、10、2、7、12、4、9、1、6、11、3,一直下去,只要表中有一个空位,就可以探测到它。用质数作为数组容量使得任何数想整除它是不可能的,因此探测序列最终会检查到所有单元。
相关文章推荐
- 哈希表中数组的容量为什么是质数
- 观V8源码中的array.js,解析 Array.prototype.slice为什么能将类数组对象转为真正的数组?
- 为什么求模运算要用素数(质数)—— 哈希表设计
- 从内存上解析c++中数组为什么不支持多态
- 为什么求模运算要用素数(质数)—— 哈希表设计
- 为什么哈希表长度须要是质数?
- 什么是 哈希表 HashMap 中数组的 size 为什么必须是 2 的整数次幂
- 数组对象的反序列化解析
- 如果改变了形参数组的值 从而在调用函数期间 形参数组就和实参数组共占同一段内存单元 为什么形参数组从实参数组那里得到起始地址后 请问各位C语言高手:当用数组名作函数参数时 也就该变了实参数组的值
- php xml 解析成数组(目前仅支持5级,需要照样添加代码就行)
- 为什么数组是从零开始?好处是。。。
- 为什么openhip启动后nslookup就能解析那些.hip为后缀的域名?
- 实例解析C++/CLI之头文件、内联函数与数组
- 为什么不能在构造函数中初始化函数指针数组
- Web Service学习笔记:WebService特性和数组类型解析
- 【翻译】Programming Ruby——数组,哈希表和控制结构
- [转贴]new 一个数组,然后对数组pp越界访问,delete []pp 时出错,为什么?
- C# 哈希表结合动态数组的简单操作和应用
- 为什么数组是常量
- 将属性的XML解析成对象数组列表