【哈希函数的构造】
1、直接定址法
取关键字或关键字的某个线性函数作哈希地址,即 或 (a, b为常数)
特点:直接定址法所得地址集合与关键字集合大小相等,不会发生冲突,但实际中很少使用。
2、数字分析法
对关键字进行分析,取关键字的若干位或组合作为哈希地址。
特点:适用于关键字位数比哈希地址位数大,且可能出现的关键字事先知道的情况。
3、平方取中法
将关键字平方后取中间几位作为哈希地址。
特点:一个数平方后中间几位和数的每一位都有关,则由随机分布的关键字得到的散列地址也是随机的。散列函数所取的位数由散列表的长度决定。这种方法适于不知道全部关键字情况,是一种较为常用的方法。
4、折叠法
将关键字分割成位数相同的几部分(最后一部分可以不同),然后取这几部分的叠加和作为哈希地址。
数位叠加有移位叠加和间界叠加两种。
5、除留余数法(常用)
取关键字被某个不大于哈希表表长 的数 除后所得余数作哈希地址,即
特点:利用这种方法的关键是 的选取, 选的不好,容易产生同义词。
6、随机数法
取关键字的随机函数值作哈希地址,即
特点:当散列表中关键字长度不等时,该方法比较合适。
【冲突处理的方法】
1、开放定址法
基本方法:当冲突发生时,形成某个探测序列;按此序列逐个探测散列表中的其他地址,直到找到给定的关键字或一个空地址(开放的地址)为止,将发生冲突的记录放到该地址中。
散列地址的计算公式是:
其中:
:哈希函数;
:散列表长度;
:第i次探测时的增量序列;
:经第
次探测后得到的散列地址。
(1)线性探测法
将散列表 看成循环向量。当发生冲突时,从初次发生冲突的位置依次向后探测其他的地址。
增量序列为:
设初次发生冲突的地址是 ,则依次探测 直到 时又循环到表头,再次探测 直到 。
探测过程终止的情况是:
- 探测到的地址为空:表中没有记录。若是查找则失败;若是插入则将记录写入该地址
- 探测到的地址有给定的关键字:若是查找则成功;若是插入则失败;
- 直到T[h]:仍未探测到空地址或给定的关键字,散列表满。
(2)二次探测法
增量序列为:
(3)伪随机探测法
增量序列使用一个伪随机函数来产生一个落在闭区间 的随机序列。
2、再哈希法
构造若干个哈希函数,当发生冲突时,利用不同的哈希函数再计算下一个新哈希地址,直到不发生冲突为止。
即:
其中, :一组不同的哈希函数。第一次发生冲突时,用 计算,第二次发生冲突时,用 计算 … 依此类推直到得到某个 不再冲突为止。
3、链地址法
方法:将所有关键字为同义词(散列地址相同)的记录存储在一个单链表中,并用一维数组存放链表的头指针。
设散列表长为 ,定义一个一维指针数组: 。
其中 是结点类型,每个分量的初值为空。凡散列地址为 的记录都插入到以 为头指针的链表中,插入位置可以在表头或表尾或按关键字排序插入。
4、建立公共溢出区
方法:在基本散列表之外,另外设立一个溢出表保存与基本表中记录冲突的所有记录。
设散列表长为 ,设立基本散列表 ,每个分量保存一个记录;溢出表 ,一旦某个记录的散列地址发生冲突,都填入溢出表中。