1.散列表(Hash)
查找的本质: 已知对象找位置。
有序安排对象:全序、半序
直接“算出”对象位置:散列
时间复杂度几乎是常量:O(1),即查找时间与问题规模无关
散列查找法的两项基本工作:
计算位置:构造散列函数确定关键词存储位置;
解决冲突:应用某种策略解决多个关键词位置相同的问题
散列(Hashing) 的基本思想是:
①以关键字key为自变量,通过一个确定的函数 h(散列函数),计算出对应的函数值h(key),作为数据对象的存储地址。
②可能不同的关键字会映射到同一个散列地址上,即h(keyi) = h(keyj)(当keyi ≠keyj),称为“冲突(Collision)”。
----需要某种冲突解决策略
2.散列函数的构造方法
散列函数两个关键:
①计算简单,以便提高转换速度;
②关键词对应的地址空间分布均匀,以尽量减少冲突。
数字关键词的散列函数构造
①直接定址法
取关键词的某个线性函数值为散列地址,即
h(key) = a * key + b (a、b为常数)
②除留余数法
散列函数为:h(key) = key mod p (一般p取素数)
③数字分析法
分析数字关键字在各位上的变化情况,取比较随机的位作为散列地址
Eg:取11位手机号码key的后4位作为地址:
散列函数为:h(key) = atoi(key+7) (char *key)
④折叠法
把关键词分割成位数相同的几个部分,然后叠加
Eg: 56793542
542
793
+ 056
———
1391
h(56793542) = 391
⑤平方取中法
Eg: 56793542
56793542
x 56793542
—————————
3225506412905764
h(56793542) = 641
字符关键词的散列函数构造
①一个简单的散列函数——ASCII码加和法
对字符型关键词key定义散列函数如下:
h(key) = (Σkey[i]) mod TableSize
②简单的改进——前3个字符移位法(易造成空间浪费)
h(key)=(key[0]*27^2 + key[1]*27 + key[2]) mod TableSize
③好的散列函数——移位法
涉及关键词所有n个字符,并且分布得很好:
Eg:h(“abcde”)=‘a’*324+’b’*323+’c’*322+’d’*32+’e’
Index Hash ( const char *Key, int TableSize )
{
unsigned int h = 0; /* 散列函数值,初始化为0 */
while ( *Key != ‘\0’) /* 位移映射 */
h = ( h << 5 ) + *Key++;
return h % TableSize;
}
……