1.什么是哈希表?
哈希表:根据设定的哈希函数H(key)和处理冲突的方法将一组关键字映射到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这种表便称为哈希表,这一映像过程称为哈希造表或散列,所得的存储位置称哈希地址或散列地址。
2.哈希表的特点:
(1)哈希函数是一个映射,因此哈希函数的设定很灵活,只要使得任何关键字由此所得的哈希函数值都落在表允许的长度范围内即可;
(2)对不同的关键字可能得到同一哈希地址,即key1≠key2,而f(key1)=f(key2),这种现象叫“冲突”。“冲突”只能减少不能避免,因为关键字数量巨大,而地址值只能为哈希表中的值,数量较小。
3.常用的构造哈希函数
1.直接定址法
取关键字的某个线性函数值为哈希地址。即:H(key)=key或H(key)=a*key+b,实际中很少用。
2.数字分析法
对关键字进行分析,尽量找随机性大的数字。
3.平方取中法
取关键字平方后的中间几位为哈希地址,这是一种较常用的构造哈希函数的方法。取的位数由表长决定。
4.折叠法
将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的折叠和(舍去进位)作为哈希地址,这方法称为折叠法。关键字位数很多,而且关键字中每一位上数字分布大致相同时,可以采用折叠法得到哈希地址。
5.除留余数法
取关键字被某个不大于哈希表表长m的数p,除后所得的余数作为哈希地址。即:H(key)=key MOD p,P≤m
这是一种最简单,也是最常用的构造哈希函数的方法。它不仅可以对关键字直接取模(MOD),也可以在折叠、平方取中等运算之后取模。
6.随机数法
选择一个随机函数,取关键字的随机函数值作为它的哈希地址,即H(key)=random(key),其中random为随机函数,通常,当关键字长度不等时采用此方法构造哈希函数较恰当。
4.处理“冲突”的方法
1.开放定址法
Hi=(H(key)+di) MOD m i=1,2,...,k(k≤m-1)
其中,H(key)为哈希函数;m为哈希表长;d为增量序列,可有下列3中取法:(1)di=1,2,3,...,m-1,称为线性探测再散列;(2)di=12,-12,...,±k2,(K≤m/2)
称为二次探测再散列;(3)di=伪随机数序列,称为伪随机数探测再散列。下面举例说明:
H(key)=key MOD 11,哈希表中已有17,60,29,现在放入38
0 1 2 3 4 5 6 7 8 9 10
60 | 17 | 29 |
插入前
60 | 17 | 29 | 38 |
线性探测再散列
38 | 60 | 17 | 29 |
二次探测再散列
38 | 60 | 17 | 29 |
伪随机数探测再散列
开放定址法会产生“二次聚集”即:两个第一哈希地址不同的记录争夺同一后继哈希地址的现象。
2.再哈希法
Hi=RHi(key) i=1,2,...,k
RHi均是不同的哈希函数,即在同义词产生地址冲突时计算另一个哈希函数地址,知道冲突不再发生。这种方法不易产生“聚集”,但增加了计算时间。
3.链地址法
将所有关键字为同义词的记录存储在同一线性链表中。假设某哈希函数产生的哈希地址在区间[0,m-1]上,则设立一个指针型向量Chain ChainHash[m];
其中每个分量的初始状态都是空指针。凡哈希地址为i的记录都插入到头指针为Chain[i]的链表中。在链表中的插入位置可以在表头或者表尾;也可以在中间,以保持同义词在同一线性表中按关键词有序。
4.建立一个公共溢出区
将发生冲突的关键词填入溢出区。
4.哈希表的查找即分析
在一般情况下,处理冲突相同的哈希表,其平均查找长度依赖于哈希表的装填因子。
哈希表的装填因子定义为:α=表中填入的记录数/哈希表的长度
哈希表的平均查找长度是α的函数,而不是n的函数。由此,不管n多大,我们总是可以选择一个合适的填装因子以便将平均查找长度限定在一个范围内。
来源:https://www.cnblogs.com/dandandeweiyi/p/4684223.html