哈希表的设计与冲突解决

来源:互联网 发布:张玉宁荷甲数据 编辑:程序博客网 时间:2024/05/16 08:25

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

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

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

1)如何构造哈希函数

2)如何处理冲突。

8.4.1 哈希函数的构造方法

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

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

1数字分析法

如果事先知道关键字集合,并且每个关键字的位数比哈希表的地址码位数多时,可以从关键字中选出分布较均匀的若干位,构成哈希地址。例如,有80个记录,关键字为8位十进制整数d1d2d3…d7d8,如哈希表长取100,则哈希表的地址空间为:00~99。假设经过分析,各关键字中d4d7的取值分布较均匀,则哈希函数为:h(key)=h(d1d2d3…d7d8)=d4d7。例如,h(81346532)=43h(81301367)=06。相反,假设经过分析,各关键字中d1d8的取值分布极不均匀,d1 都等于5d8都等于2,此时,如果哈希函数为:h(key)=h(d1d2d3…d7d8)=d1d8,则所有关键字的地址码都是52,显然不可取。

2平方取中法

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

例:我们把英文字母在字母表中的位置序号作为该英文字母的内部编码。例如K的内部编码为11E的内部编码为05Y的内部编码为25A的内部编码为01, B的内部编码为02。由此组成关键字“KEYA”的内部代码为11052501,同理我们可以得到关键字“KYAB”、“AKEY”、“BKEY”的内部编码。之后对关键字进行平方运算后,取出第7到第9位作为该关键字哈希地址,如图8.23所示。

       

关键字

内部编码

内部编码的平方值

H(k)关键字的哈希地址

KEYA

11050201

122157778355001

778

KYAB

11250102

126564795010404

795

AKEY

01110525

001233265775625

265

BKEY

02110525

004454315775625

315

8.23平方取中法求得的哈希地址

3分段叠加法

这种方法是按哈希表地址位数将关键字分成位数相等的几部分(最后一部分可以较短),然后将这几部分相加,舍弃最高进位后的结果就是该关键字的哈希地址。具体方法有折叠法移位法。移位法是将分割后的每部分低位对齐相加,折叠法是从一端向另一端沿分割界来回折叠(奇数段为正序,偶数段为倒序),然后将各段相加。例如:key=12360324711202065,哈希表长度为1000,则应把关键字分成3位一段,在此舍去最低的两位65,分别进行移位叠加和折叠叠加,求得哈希地址为105907,如图8.24所示。

1 2 3 12 3

6 0 3 30 6

2 4 7 24 7

1 1 2 21 1

+0 2 0 +0 2 0

—————————————————

1 1 0 5 90 7

a)移位叠加(b)折叠叠加

8.24由叠加法求哈希地址

4除留余数法

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

hk=k% p ,其中%为模p取余运算。

例如,已知待散列元素为(18756043549046),表长m=10p=7,则有

h(18)=18 % 7=4 h(75)=75 % 7=5h(60)=60 % 7=4

h(43)=43 % 7=1 h(54)=54 % 7=5h(90)=90 % 7=6

h(46)=46 % 7=4

此时冲突较多。为减少冲突,可取较大的m值和p值,如m=p=13,结果如下:

h(18)=18 % 13=5 h(75)=75 % 13=10h(60)=60 % 13=8

h(43)=43 % 13=4 h(54)=54 % 13=2h(90)=90 % 13=12

h(46)=46 % 13=7

此时没有冲突,如图8.25所示。

0 1 23 4 5 67 8 9 1011 12

54

43

18

46

60

75

90

 

8.25除留余数法求哈希地址

5伪随机数法

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

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

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

l关键字的长度。

l哈希表大小。

l关键字分布情况。

l记录查找频率

8.4.2处理冲突的方法

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

1.开放定址法

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

Hi=Hkey+di% m i=12…,n

其中Hkey)为哈希函数,m为表长,di称为增量序列。增量序列的取值方式不同,相应的再散列方式也不同。主要有以下三种:

l线性探测再散列

dii=123m-1

这种方法的特点是:冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。

l二次探测再散列

di=12-1222-22k2-k2( k<=m/2 )

这种方法的特点是:冲突发生时,在表的左右进行跳跃式探测,比较灵活。

l伪随机探测再散列

di=伪随机数序列。

具体实现时,应建立一个伪随机数发生器,(如i=(i+p) % m),并给定一个随机数做起点。

例如,已知哈希表长度m=11,哈希函数为:Hkey= key % 11,则H47=3H26=4H60=5,假设下一个关键字为69,则H69=3,与47冲突。如果用线性探测再散列处理冲突,下一个哈希地址为H1=3 + 1% 11 = 4,仍然冲突,再找下一个哈希地址为H2=3 + 2% 11 = 5,还是冲突,继续找下一个哈希地址为H3=3 + 3% 11 = 6,此时不再冲突,将69填入5号单元,参图8.26 (a)。如果用二次探测再散列处理冲突,下一个哈希地址为H1=3 + 12% 11 = 4,仍然冲突,再找下一个哈希地址为H2=3 - 12% 11 = 2,此时不再冲突,将69填入2号单元,参图8.26 (b)。如果用伪随机探测再散列处理冲突,且伪随机数序列为:259……..,则下一个哈希地址为H1=3 + 2% 11 = 5,仍然冲突,再找下一个哈希地址为H2=3 + 5% 11 = 8,此时不再冲突,将69填入8号单元,参图8.26 (c)

0 12 3 45 6 78 9 10

47

26

60

69

a用线性探测再散列处理冲突

0 12 3 45 6 78 9 10

69

47

26

60

b用二次探测再散列处理冲突

0 12 3 45 6 78 9 10

47

26

60

69

c用伪随机探测再散列处理冲突

8.26开放地址法处理冲突

从上述例子可以看出,线性探测再散列容易产生“二次聚集”,即在处理同义词的冲突时又导致非同义词的冲突。例如,当表中i, i+1 ,i+2三个单元已满时,下一个哈希地址为i,i+1 ,i+2,或i+3的元素,都将填入i+3这同一个单元,而这四个元素并非同义词。线性探测再散列的优点是:只要哈希表不满,就一定能找到一个不冲突的哈希地址,而二次探测再散列和伪随机探测再散列则不一定。

2.再哈希法

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

Hi=RH1keyi=12k

当哈希地址Hi=RH1key)发生冲突时,再计算Hi=RH2key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。

3.链地址法

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

4建立公共溢出区

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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 月经摊迟三天内裤有白带怎么办 怀孕内裤上有黄黄的分泌物怎么办 老公出轨想离婚但舍不得孩子怎么办 老婆出轨离婚又舍不得家我该怎么办 怀孕一个月刚刚自慰有点流血怎么办 老公出轨还不知道悔改妻子怎么办 离婚了前妻户口还在再婚怎么办 怀孕六个月内裤老是湿有异味怎么办 怀孕五个月内裤总是湿有异味怎么办 耳朵里面有个洞老是流水冒浓怎么办 宝宝拉粑粑有臭酸味怎么回事怎么办 老婆晚上回家内裤是湿的尿味怎么办 怀孕五个月下身痒内裤湿怎么办 哺乳期奶水太多经常弄湿衣服怎么办 麻料裙子一坐下就皱怎么办 不小心把答题卡弄皱了怎么办 嘴巴又干又黏又臭怎么办 不小心把红枣核吞了怎么办 小天才电话手表被偷了怎么办 18k金被火烧黑了怎么办 衣服掉色染到别的衣服上怎么办 夏天太阳太毒刚发芽的花种子怎么办 长斑了怎么办 喝玫瑰花茶能祛斑吗 烧纸火纸迷信纸利润太低怎么办 刚买的绣球花花有点蔫怎么办 ZF葡7正常佩戴动能太满怎么办 怀孕初期老婆婆做的菜不好吃怎么办 调节协议已签字不签收调解书怎么办 给晋中苗圃拉了树苗没拿上钱怎么办 多肉旁边长出好多小株怎么办 烤瓷牙制备时颌关系不够怎么办 对门放石头正对我家大门怎么办 合租的室友关门开门特别大声怎么办 三周岁的宝宝小阴唇再次粘连怎么办 小阴唇内侧长了毛囊炎很大疼怎么办 小阴唇上一个黄豆大的硬疙瘩怎么办 梦幻西游手游金币兑换上限了怎么办 手机放裤子口袋里易拔出怎么办 两个月宝宝拉肚子怎么办吃纯母乳 花王泡沫染停留时间太久怎么办 ps右下角的图层图标隐藏了怎么办