一、散列查找的基本思想:
散列技术:
在记录的存储位置和它的关键码key之间建立一个确定的对应关系H,使得每个关键字key和唯一的存储位置H(key)相对应。存储记录时,根据这个对应关系找到关键码的映射地址,并按此地址存储该记录;查找记录时,根据这个对应关系找到待查关键码的映射地址,并按此地址访问该记录,这种查找技术就称为散列技术。采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为散列表;将关键码映射为散列表中适当位置的函数称为散列函数,所得的存储位置称为散列地址。
散列技术需要考虑的两个问题:
1.散列函数的设计。力求简单、均匀、存储利用率高的散列函数。
2.冲突的处理。
二、散列函数的设计。
散列函数遵循的基本原则:
1.计算简单。散列函数应该不是很大的计算量,否则会降低查找效率。
2.函数值(即散列地址)分布均匀,希望散列函数能够把记录以相同的概率散列到散列表的所有地址空间中,这样才能保证存储空间的有效利用,并减少冲突。
三种常见的散列函数:
直接定址法:
直接定址法的散列函数是关键码的线性函数,即H(key) = a x key + b , 其中a, b为常数。
例如:关键码集合为{10,30,50,70,80},选取的散列函数为H(key) = key / 10,则散列表如下图所示:
评价:
直接定址法的特点是不会产生冲突,但实际应用中能使用这种散列函数的情况很少,它适用于事先知道关键码的分布,关键码结合不是很大且连续性较好的情况。
除留余数法:
除留余数法的基本思想是选择某个适当的正整数p,以关键码除以p的余数作为散列地址。
H(key) = key mod p.
一般情况下,如果散列表的长度为m, 通常选p为小于或等于表长(最好接近m)的最小素数或不包含小于20质因子的合数。
评价:
除留余数法是一种最简单、也是最常用的构造散列函数的方法,并且这种方法不要求事先知道关键码的分布。
平方取中法:
平方取中法是对关键码平方后,按散列表大小,取中间的若干位作为散列地址(简称平方后截取)。
之所以这样,是因为一个数平方后,中间的几位分布较均匀,从而冲突发生的概率较小。
例如:关键码1234,假设散列地址是2位,1234^2 = 1522756,选取中间的2位作为散列地址,可以选22,也可以选27.
三、处理冲突的方法
1.开放定址法:
用开发定址法处理冲突得到的散列表叫做闭散列表。
开放地址法处理冲突的方法是,如果关键码得到的散列地址产生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,他的散列地址总能找到,并将记录存入。找下一个空散列地址的方法通常有线性探测法和二次探测法。
1.1线性探测法:
当冲突发生时,线性探测法从冲突位置的下一个位置起,依次寻找空的散列地址,对于键值key,闭散列表的长度为m, 发生冲突时,寻找下一个散列地址的公式为:
(H(key) + di) % m (di = 1,2,3 ,4,...m-1)
1.2二次探测法
2.拉链法(链地址法)
用拉链法处理冲突构造的散列表叫做开散列表。
四、散列查找的性能分析
影响冲突概率的主要三个因素:
1.散列函数是否均匀。
2.处理冲突的方法。
3.散列表的装填因子。
开散列表和闭散列表的比较:
未完待续...