哈希表及处理冲突的方法

http://www.360doc.com/content/14/0721/09/16319846_395862328.shtml

哈希法又称 散列法、杂凑法以及关键字地址计算法 等,相应的表称为 哈希表。 这种方法的基本思想是: 首先在元素的关键字 k 和元素的存储位置 p 之间建立一个对应关系 f ,使得 p=f(k) , f 称为哈希函数 。创建哈希表时,把关键字为 k 的元素 直接存入地址为 f(k) 的单元;以后当查找关键字为 k 的元素时,再利用哈希函数计算出该元素的存储位置 p=f(k) ,从而达到按关键 字直接存取元素的目的。

    当关键字集合很大时,关键字值不同的元素可能会映象到哈希表的同一地址上 ,即  k1 ≠ k2  ,但  H ( k1 ) =H ( k2 ),这种现象称为冲突,此时称 k1 和 k2 为同义词。实际中,冲突是不可避免的,只能通过改进哈希函数的性能来减少冲突。

综上所述,哈希法主要包括以下两方面的内容:

 1 )如何构造哈希函数

 2 )如何处理冲突。

8.4.1    哈希函数的构造方法

     构造哈希函数的原则是: ① 函数本身便于计算; ② 计算出来的地址分布均匀,即对任一关键字 k , f(k)  对应不同地址的概率相等,目的是尽可能减少冲突。

下面介绍构造哈希函数常用的五种方法。

1 .   数字分析法

       如果事先知道关键字集合,并且每个关键字的位数比哈希表的地址码位数多时,可以从关键字中选出分布较均匀的若干位,构成哈希地址。

2 .   平方取中法

当无法确定关键字中哪几位分布较均匀时,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为哈希地址。这是因为:平方后中间几位和关键字中每一位都相关,故不同关键字会以较高的概率产生不同的哈希地址。

3 .   分段叠加法

       这种方法是按哈希表地址位数将关键字分成位数相等的几部分(最后一部分可以较短),然后将这几部分相加,舍弃最高进位后的结果就是该关键字的哈希地址。具体方法有折叠法与移位法。移位法是将分割后的每部分低位对齐相加,折叠法是从一端向另一端沿分割界来回折叠(奇数段为正序,偶数段为倒序),然后将各段相加。

4 .   除留余数法

假设哈希表长为 m , p 为小于等于 m 的最大素数,则哈希函数为

h ( k ) =k  %  p  ,其中 % 为模 p 取余运算。

 

5 .   伪随机数法

     采用一个伪随机函数做哈希函数,即 h(key)=random(key) 。

在实际应用中,应根据具体情况,灵活采用不同的方法,并用实际数据测试它的性能,以便做出正确判定。通常应考虑以下五个因素   :

l           计算哈希函数所需时间   (简单)。

l           关键字的长度。

l           哈希表大小。

l           关键字分布情况。

l           记录查找频率

8.4.2   处理冲突的 方法

    通过构造性能良好的哈希函数,可以减少冲突,但一般不可能完全避免冲突,因此解决冲突是哈希法的另一个关键问题。创建哈希表和查找哈希表都会遇到冲突,两种情况下解决冲突的方法应该一致。下面以创建哈希表为例,说明解决冲突的方法。常用的解决冲突方法有以下四种:

1.            开放定址法

这种方法也称 再散列法 , 其基本思想是:当关键字 key 的哈希地址 p=H ( key )出现冲突时,以 p 为基础,产生另一个哈希地址 p1 ,如果 p1 仍然冲突,再以 p 为基础,产生另一个哈希地址 p2 , … ,直到找出一个不冲突的哈希地址 pi  , 将相应元素存入其中。

 

2.            再哈希法

     这种方法是同时构造多个不同的哈希函数:

       H i =RH 1 ( key )   i=1 , 2 , … , k

当哈希地址 H i =RH 1 ( key )发生冲突时,再计算 H i =RH 2 ( key )……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。

3.            链地址法

     这种方法的基本思想是将所有哈希地址为 i 的元素构成一个称为同义词链的单链表 ,并将单链表的头指针存在哈希表的第 i 个单元中,因而查找、插入和删除主要在同义词链中进行。链地址法适用于经常进行插入和删除的情况。

4.    建立公共溢出区

  这种方法的基本思想是:将哈希表分为基本表溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表

posted @ 2017-03-10 16:05  xiaobaxiing  阅读(293)  评论(0编辑  收藏  举报