散列表(哈希表)查找
- 我们要在a[ ]中查找key关键字的记录:
—— 顺序表查找:挨个儿比较
—— 有序表查找:二分法查找
—— 散列表查找:?
散列表的查找步骤
- 当存储记录时,通过散列函数计算出记录的散列地址
- 当查找记录时,我们通过同样的是散列函数计算记录的散列地址,并按此散列地址访问该记录。
构造散列函数的两个基本原则
好的散列函数 = 计算简单+分布均匀
-
直接定址法
—— 例1:有一个从1到100岁的人口数字统计表,其中,年龄作为关键字,哈希函数取关键字自身。
即:f(key)= key
—— 例2:如果现在要统计的是1980年以后出生的人口数,那么我们对出生年份这个关键字可以变换为:用年份减去1980的值来作为地址。
即:f(key)= key - 1980
-
数字分析法
数字分析法通常适合处理关键字位数比较大的情况,例如我们现在要存储某家公司员工登记表,如果用手机号码作为关键字,那么我们发现抽取后面的四位数字作为散列地址是不错的选择。
-
平方取中法
平方取中法是将关键字平方之后取中间若干位数字作为散列地址。 -
折叠法
折叠法是将关键字从左到右分割成位数相等的几部分,然后将这几部分叠加求和,并按散列表表长取后几位作为散列表地址。 -
除留余数法
—— f(key)= key mod p (p<=m)
我们对有12个记录的关键字构造散列表时,就可以用除留取余法:
p的选择是关键,如果对于下面这个表格的关键字,p还选择12的话,那得到的情况未免也太糟糕了:
p的选择很重要,如果我们把p改为11,那结果就另当别论了:
-
随机数法
选择一个随机数,取关键字的随机函数值为它的散列地址。
即:f(key)= random(key)
这里的random是随机函数,当关键字的长度不等时,采用这个方法构造散列函数是比较合适的。
处理散列冲突的方法
-
开放定址法
所谓的开放定址法就是一旦发生冲突,就去寻找下一个空的散列表,只要散列表足够大,空的散列地址总能找到,并将记录存入。
他的公式是:
fi(key)= (f(key)+di)MOD m (di = 1,2,…m-1)
-
再散列函数法
fi(key) = RHi(key)(i = 1,2,3,…k) -
链地址法
-
公共溢出区法(常用方法)