联系hashgameCONTACT hashgame
地址:广东省广州市
手机:13988889999
电话:020-88889999
邮箱:admin@qq.com
查看更多
Rhashgamehashgame
你的位置: 首页 > hashgame

数据结构(C语言版):第4章 哈希表HASH GAME - Online Skill Game ET 300

发布时间:2025-04-24 19:44:59  点击量:

  HASH GAME - Online Skill Game GET 300

数据结构(C语言版):第4章 哈希表HASH GAME - Online Skill Game GET 300

  4.4哈希表的实现链地址哈希表的实现开放定址哈希表的实现4.5哈希表的查找性能4.1哈希表的概念记录的存储位置与关键字之间不存在确定关系。在查找记录时,需要进行关键字比较,其查找的效率依赖于查找过程中所进行的比较次数。如果记录的关键字与存储位置存在某种一一映射关系,那么就可以通过待查记录的关键字,计算其存储位置,直接找到该记录。哈希表是一种高效的查找结构利用记录的关键字确定其存储位置,不需比较或只需少量比较关键字。把关键字集合K映像到一个有限的连续的地址集(区间)D的映射关系H可表示为H(key):K→D,key∈KH称为哈希函数或散列函数。按哈希函数构建的表称为哈希表。D的大小m称为哈希表的地址区间长度。例子假设要建立一个地址区间长度为13的哈希表,哈希函数为H(key)=Ord(关键字第一个字母)-1)/2其中函数Ord求字母在字母表中的序号。例如,字母A在字母表中的序号为1,Ord(‘A’)=1。现将关键字依次为Zhao,Qian,Sun,Li,Wu,Chen,Han的7个记录插入该哈希表。第一个关键字Zhao的哈希函数值为

  (26-1)/2=12将Zhao存入12号单元。以此类推,得到的结果:HanChenLiQianSunWuZhao冲突与同义词若要查找记录,则只需计算记录的关键字的哈希函数值,就可以直接找到该记录。例如,要查找关键字为Chen的记录,计算得到哈希函数值1,就在1号单元得到该记录。若在哈希表中插入关键字Xie,其哈希函数值为11,但11号单元已被Wu占据。由此可见,不同关键字的哈希函数值可能相同,即:H(key1)=H(key2),

  key1≠key2这种现象称之为冲突。哈希函数值相同的关键字称为同义词。HanChenLiQianSunWuZhao如何避免冲突为了避免出现冲突,可以换一个哈希函数:H(key)=Ord(关键字第一个字母)%13记录关键字对应的序列还是(Zhao,Qian,Sun,Li,Wu,Chen,Han)。若加入关键字Xie,不会产生冲突。但再加入关键字Dai,其哈希函数值为4,与Qian冲突。HanChenLiQianSunWuZhaoXie哈希表的定义在一般情况下,哈希函数是一种压缩映射,即关键字集大于哈希地址集,这就不可避免产生冲突,因此在构造哈希表时不仅要设计一个好的哈希函数,而且要设定一个处理冲突的方法。根据设定的哈希函数和处理冲突的方法将一组关键字映像到一个连续的有限地址集上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这种表称为哈希表,这一映像过程称为哈希造表或散列,所得存储位置称哈希地址或散列地址。4.2哈希函数的构造方法若对于关键字集合中的任一个关键字,经哈希函数映像到地址集合中任何一个地址的概率是相等的,则称此类哈希函数为均匀的哈希函数。哈希函数越均匀,发生冲突的概率越低。哈希函数的构造方法有很多,设计时应注意两个原则:第一,计算过程尽量简单;第二,哈希函数尽量均匀。哈希函数构造方法直接定址法除留余数法数字分析法折叠法平方取中法4.2.1直接定址法最简单的直接定址法直接用关键字key作为哈希地址,即:H(key)=key。例如一个儿童人口统计表,记录了从0岁到12岁的儿童人口数目,以年龄作为关键字,哈希函数取关键字自身。要查找11岁的儿童人数时,直接读出第11项即可。地址01…1112年龄01…1112人数980800…495107直接定址法一般情况下,直接定址法可通过对关键字缩放和平移,以获得合适的地址区间,即以下线性函数H(key)=a×key+b

  其中,a为缩放系数,b为平移系数。例如某公司有在职员工各年龄人数统计表,年龄从18周岁到65周岁,就可以采用将关键字年龄减去18来作为数据的存储单元,即a=1,b=-18。员工各年龄人数统计的哈希函数示例见下表。地址01…4647年龄1819…6465人数1225…23204.2.2除留余数法对于地址区间长度为m的哈希表,除留余数法取某个不大于m的数p为模,将哈希函数定义为H(key)=key%p(p≤m)。除留余数法简单常用,不仅可以对关键字直接取模,也可以在折叠、平方取中等运算后再取模。值得注意的是模p的选择十分重要。理论研究表明,模p取不大于m且最接近m的素数,或不包含小于20的质因子的合数时,可使哈希地址尽可能均匀地分布在地址空间。表6.3给出了模p建议值示例。为保证求得的哈希函数值在地址区间长度范围以内,除留余数法常与其它方法配合使用。地址区间长度m21000模p39974.2.3数字分析法当关键字的位数很多时,可以通过对关键字的各位进行分析,去掉分布不均匀的位,将分布均匀的位提取出来作为哈希值。数字分析法取关键字中某些取值分布较均匀的数位作为哈希地址。该方法适合于关键字位数较多,且能预测关键字各位分布均匀度的情况。例子例如构造一个数据元素个数n=60,哈希地址空间长度m=100的哈希表。对关键字分析发现,关键字的第1、2、3、6位取值比较集中,不宜作为哈希地址,第4、5、7、8位取值较均匀,可选取其中的两位作为哈希地址。设选取最后两位作为哈希地址8个关键字的哈希地址分别为:02,75,28,34,15,38,62,20。4.2.4折叠法折叠法将关键字分割成位数相同的若干部分(最后一部分的位数可以较少),并取各部分的叠加和(舍去进位)作为哈希函数。折叠法适用于关键字位数较多且每一位数字分布大致均匀的情况。分割后的叠加可分为移位叠加和Z形叠加两种方法移位叠加是将分割后每一部分的最低位对齐,然后相加;Z形叠加是从一端向另一端沿分割界来回折叠,然后对齐相加。例子设当哈希表的地址区间长度为10000时,关键字key=891,允许的地址空间为四位十进制数。用移位叠加得到的哈希地址是2308,而用Z形叠加所得到的哈希地址是5115。4.2.5平方取中法平方取中法先取关键字的平方,然后根据哈希表地址区间长度m的大小,选取平方数的中间若干位作为哈希地址。通过取平方扩大关键字之间的差别,而平方值的中间若干位和这个数的每一位都相关,使得不同关键字的哈希函数值分布较为均匀,不易产生冲突。设哈希表地址区间长度为1000,可取关键字平方值的中间三位。关键字关键字的平方哈希函数值138平方取中法的哈希函数算法实现了一个取关键字平方值的万千百三位的哈希函数

  }一般情况下,应该根据关键字的取值范围,来确定取关键字平方值的中间哪几位做为哈希地址。4.3处理冲突的方法构造哈希表时,根据关键字集合的特点选择合适的哈希函数,使哈希地址尽量均匀地分布在哈希表的地址区间内,以避免或减少冲突。但哈希函数的构造,与关键字的长度、哈希表的大小、关键字的实际取值状况等许多因素有关,而且有些因素事前不能确定。所以,避免冲突不易做到。关键在于如何处理冲突。4.3.1链地址法链地址法将关键字为同义词的记录链接在同一个单链表中。设哈希表地址区间长度为m,则可将哈希表定义为一个由m个头指针组成的指针数组T[0..m-1]。凡是哈希地址为i的记录,均插入到以T[i]为头指针的单链表中,称该单链表为i同义词链表。T中各分量的初值置为空指针。链地址法实例假设有8个关键字22,41,53,46,30,13,12,67,哈希表的地址区间长度为11,哈希函数为H(key)=(3*key)%11,采用链地址法处理冲突建立哈希表.∧∧∧∧∧4.3.2开放定址法开放定址法是在哈希表的地址空间内解决冲突。插入时一旦发生冲突,可使用某种探测技术在哈希表中计算得到另一个地址,若不冲突,则插入,否则求下一个地址,直到探测到空闲地址为止,则插入新结点到该地址单元。在探测过程中,求得的一系列地址称为探测地址序列。查找的探测过程与插入相同。沿着探测地址序列逐个查找,若找到给定的关键字,则查找成功;若探测到一个空闲地址,则表明表中无待查的关键字,查找失败。下面介绍两种常用的开放定址法:线性探测法和二次探测法。1.线性探测法线性探测法(LinearProbing)的基本思想是:假定哈希函数为H(key),哈希表的地址区间长度为m,并将哈希表看成是一个循环空间,则线性探测法的探测地址序列可表示为: Hi=(H(key)+i)%m1≤i≤m-1其中,Hi表示出现冲突时,第i次探测的地址空间。线,哈希表的地址区间长度为11,哈希函数为H(key)=(3*key)%11,采用线线性探测法处理冲突优点:思路清晰,算法简单缺点:很容易产生堆聚现象。所谓堆聚现象,就是存入哈希表的记录在表中连成一片。按照线性探测法处理冲突,如果生成哈希地址的连续序列越长,则当新的记录加入该表时,与这个序列发生冲突的可能性越大。2.二次探测法二次探测法生成的探测地址序列不是连续的,而是跳跃式的,为后续待插入的记录留下空间从而减少堆聚。二次探测法的探测地址序列可表示为Hi=(H(key)+di)%m1≤i≤m-1其中,di=12,-12,22,-22,…,k2,-k2(k≤m/2),即H=H(key),H1=(H+12)%m,H2=(H-12)%m,H3=(H+22)%m,H4=(H-22)%m…二次探测法的实例假设有8个关键字22,41,53,46,30,13,12,67,哈希表的地址区间长度为11,哈希函数为H(key)=(3*key)%11,采用二次探测法处理冲突。674.4.1链地址哈希表的实现链地址哈希表的类型定义typedefstructNode{

  0H.tag12345H.rcd[].keyH.rcd1012H.Count=7-1c=14.5哈希表的查找性能对同一组关键字,设定相同的哈希函数,若采用不同的处理冲突方法,则导致实际的哈希表不同,它们的平均查找长度也不同。假设有8个关键字22,41,53,46,30,13,12,67,哈希函数为H(key)=(3*key)%11,地址区间长度为11,我们分别来计算采用链地址法线、性探测法和二次探测法处理冲突的平均查找长度。平均查找长度(链地址法)关键字序列为(22,41,53,46,30,13,12,67),哈希函数为H(key)=(3*key)%11,利用链地址法处理冲突,若记录的查找概率相同的情况下,其查找成功的平均查找长度为:ASL(8)=/8=1.375(1+1)+2+1+2+1+1+2平均查找长度(线性探测法)关键字序列为(22,41,53,46,30,13,12,67),哈希函数为H(key)=(3*key)%11,利用线性探测法处理冲突,若记录的查找概率相同的情况下,其查找成功的平均查找长度为:ASL(8)=67+6)(1+1+1+1+2+2+2/8=0平均查找长度(二次探测法)关键字序列为(22,41,53,46,30,13,12,67),哈希函数为H(key)=(3*key)%11,利用二次探测法处理冲突,若记录的查找概率相同的情况下,其查找成功的平均查找长度为:ASL(8)=111111000/8=1.875+5)(1+1+1+1+2+2+2装填因子在构造哈希表时,哈希表中插入的记录数占地址区间长度的比率称为装填因子α平均查找长度处理冲突方法相同的哈希表,其平均查找长度依赖于α,直观上来看,α越大,发生冲突的可能性就越大。可以证明:采用链地址法的哈希表查找成功时的平均查找长度为采用线性探测法的哈希表查找成功时的平均查找长度为采用二次探测法的哈希表查找成功时的平均查找长度为查找不成功时所需比较次数由于哈希表中查找不成功时所需比较次数与给定值有关,则可类似地定义哈希表中查找不成功时的平均查找长度为:查找不成功时需和给定值进行比较的关键字个数的期望值。同样可以证明,不同处理冲突的方法构成的哈希表查找不成功时的平均查找长度分别为:链地址法线性探测法二次探测法装载因子与平均查找长度这三种处理冲突的方法中,装载因子与平均查找长度在查找成功和查找不成功的关系在装载因子较小时(小于0.6时),这三种处理冲突的方法,性能相差不大;但当装载因子大于0.6后,线性探测法处理冲突的性能急剧下降;用链地址法处理冲突,随着装载因子的变化,其性能变化不大。链地址法与开放定址法链地址法处理冲突简单,且无堆聚现象,即非同义词决不会发生冲突,因此平均查找长度较短,查找效率高;链地址法中链表的结点是动态申请的,更适合事前无法确定元素个数的情况;在用链地址法构造的哈希表中,删除操作易于实现,只需删去链表上相应结点即可。而对开放地址法构造的哈希表,不能简单地将被删记录的存储单元置为空闲单元,而是打删除标记,否则将截断探测路径,影响路径上该单元之后的记录的查找;开放定址法为了减少冲突要求装填因子较小,故哈希表需设置较大的地址区间长度,耗费较多空间。而链地址法中装填因子可以大于1,但需要另设指针空间。完美哈希函数对于预先知道且规模不大的关键字集,有时可以构造完美哈希函数。完美哈希函数是指没有冲突的哈希函数,即若K的大小为n,D的大小为m,m≥n,且哈希函数H不出现同义词。若m等于n,则称为最小完美哈希函数。

【返回列表页】

顶部

地址:广东省广州市  电话:020-88889999 手机:13988889999
Copyright © 2018-2025 哈希游戏(hash game)官方网站 版权所有 非商用版本 ICP备案编: