3.1.哈希方法基本思想
- 哈希函数是一个映射,即:将关键字的集合映射到某个地址集合上。
- 在一般情况下,容易产生“冲突”现象。key1≠key2,而f(key1)=f(key2)。虽然关键字不同,但映射的两个值得地址相等,就发生了冲突。
- 很难找到一个不产生冲突的哈希函数。一般情况下,只能选择恰当的哈希函数,使冲突尽可能少地产生。
3.2.哈希表的概念
根据设定的哈希函数H(key)和所选中的处理冲突的方法,将一组关键字映象到一个有限的,地址连续的地址集(区间)上,并以关键字在地址集中的“象”作为相应记录在表中的存储位置,如此构造所得的查找表称之为**“哈希表”**。
3.3.哈希函数
- 构造方法
- 原则:
- 函数本身便于计算。
- 计算出来的地址分布均匀。
- 若是非数字关键字,则需先对其进行数字化处理。
- 原则:
- 构造哈希函数常用的方法:
-
数字分析法:设关键字集合中每个关键字都是由S位数字组成(U1,U2,…,Us),分析关键字集合中的全体,并从中提取分布若干位或它们的组合作为地址。
-
平方取中法:
-
以关键字的平方值的中间几位作为存储地址。
-
不同关键字会议较高的频率产生不同的哈希地址。
-
-
折叠法:
- 将关键字分割成若干部分,然后取它们的叠加和为哈希地址。
- 奇数段偶数取,偶数段反序取。各段叠加后的值作为哈希地址值。
-
除留余数法:假设哈希表长为m,p为小于等于m的最大素数,则哈希函数为H(k) = k%p,其中%为模p取余运算。
- 对p的要求:p要小于等于表长m的最大素数。
-
- 选择构造方法的原则:使冲突的可能性降到尽可能小。
3.4.哈希冲突
在哈希表中,尽管构造性能良好的哈希函数可以减少冲突,但实际上冲突是不可避免的。
处理冲突是为产生冲突的地址寻找下一个哈希地址。
-
开放地址法
-
为产生冲突的的地址H(key)求得一个地址序列:
-
基本思想:当关键字key的初始哈希地址h0=H(key)出现冲突时,以h0为基础,产生另一个地址h1,如果h1仍然冲突,再以h0为基础,产生另一个哈希地址h2…直到找出一个不冲突的地址hi,将对应元素存入其中。
-
再散列函数形式:
-
对增量d1有三种取法:
-
线性探测再散列:
-
d1=1,2,3…m-1;
-
di=c x i ,最简单的情况 c=1;
-
特点:当发生冲突时,顺序查看表中的下一个单元,直到找出一个空单元或查遍全表。
-
例子:关键字集合{19,01,23,14,55,68,11,82,36}
-
设定哈希函数H(key) = key MOD 11(表厂=11)
-
0 1 2 3 4 5 6 7 8 9 10 55 01 23 14 68 11 82 36 19 成功 1 1 2 1 3 6 2 5 1 失败 10 9 8 7 6 5 4 3 2 -
ASLsucc=(1+1+2+1+3+6+2+5+1)/9=22/9
-
分析失败的情况:哈希函数是对11求余,那如果失败,就意味着失败的所有情况对11求余的结果,可能的范围是0,1,2…10,一共有11种不同的可能。
-
ASLunsucc=(10+9+8+7+6+5+4+3+2+1+1)/11=56/11
-
-
二次探测再散列:
-
d1=12,-12,22,-22…,
-
特点:当发生冲突时,在表的左右进行跳跃式探测,比较灵活。
-
例子:关键字集合{19,01,23,14,55,68,11,82,36}
-
设定哈希函数H(key) = key MOD 11(表厂=11)
-
key 19 01 23 14 55 68 11 82 36 k%11 8 1 1 3 0 2 0 5 3 -
0 1 2 3 4 5 6 7 8 9 10 55 01 23 14 36 82 68 19 11 成功 1 1 2 1 2 1 4 1 3 失败 5 9 5 4 8 4 2 1 2 1 3 -
ASLsucc=(1+1+2+1+2+1+4+1+3)/9=16/9
-
ASLunsucc=(5+9+5+4+8+4+2+1+2+1+3)/11=4
-
-
伪随机探测再散列:
- d1=伪随机数序列
- 具体实现时,应建立一个伪随机数发生器。
-
-