目前为止已经介绍了顺序查找、二分查找、分块查找、二叉排序树,见作者之前的文章:
http://blog.csdn.net/u010025211/article/details/46635325
http://blog.csdn.net/u010025211/article/details/46635183
今天这篇博文将介绍哈希查找。
1.为什么要用哈希查找
之前所讲的查找方法都是需要比较待查找元素与线性表或者树中的元素才能实现。
这样的时间复杂度为O(n)或者O(log n),那么有没有可能当给定一个待查找元素x,我们通过一种特殊的计算,计算出该元素在数组A的位置i,那么就可以直接找到该元素A[i]
哈希函数就是这种特殊的计算,能够降低时间复杂度。
2.特殊计算的定义——哈希函数(散列函数)
STL中就有hashtable这种类可以直接使用,那么哈希查找是怎么实现的呢?
哈希函数的构造方法:
2.1 直接定址法:
取关键字或关键字的某个线性函数值为哈希地址。即: 地址H(key) = key 或 H(key) = a*key+b 实例:某大学从1960年开始招生,有历届招生人数统计表A,其中以年份为关键字。则哈希函数可设计为:H(key) = key - 1959 直接定址法由于关键字与存储地址存在一一对应关系,因此,不会 发生冲突现象。
Key |
1959 |
1960 |
1961 |
1962 |
H(key) |
0 |
1 |
2 |
3 |
2.2 除余法:
选择一个适当的正整数P(P≤表长),用P 去除关键字,取所得余数作为哈希地址。即:H(key) = key % P (P ≤ 表长) 除余法的关键是选取适当的P,一般选P为小于或等于哈希表的长 度m的某个素数为好。
例: m = 8,16,32,128,256,512 P = 7,13,31,127,251,503 除余法不仅可以直接对关键字取模,也可在折叠、平方取中等运算 之后取模。
2.3 平方取中法:
取关键字平方后的中间几位为哈希地址。由于一个数的平方的中间几位与这个数的每一位都有关,因而,平方取中法产生冲突的机会相对较小。平方取中法中所取的位数由表长决定。
例: K = 456 , K2 = 207936 若哈希表的长度m=102,则可取79(中间两位)作为哈希函数值。
2.4 折叠法: