通过一个待散列的线性表为和散列函数怎么知道散列值为3的个数

Hash表的“查找成功的ASL”和“查找不成功的ASL”

ASL指的是 平均查找时间

关键字序列:(7、8、30、11、18、9、14)

处理冲突:线性探测再散列法


查找成功的ASL计算方法:


以下求解过程是按照“计算机统考的计算方法”不同的老师、教材在“处理冲突”上可能会有不同的方法,所以最主要的是掌握原理即可对于考研的朋友最好掌握统考真题的解题方法。 

例子:(2010年全国硕士研究生入学统一考试计算机科学与技术学科联考计算机學科专业基础综合试题第一题)

因为现在的数据是7个填充因子是0.7。所以数组大小=7/0.7=10即写出来的散列表大小为10,下标从0~9 
第一个元素7,带叺散列函数计算得0。 
第二个元素8带入散列函数,计算得3 
第三个元素30,带入散列函数计算得6。 
第四个元素11带入散列函数,计算得5 
第五个元素18,带入散列函数计算得5;此时和11冲突,使用线性探测法得7。 
第六个元素9带入散列函数,计算得6;此时和30冲突使用线性探测法,得8 
第七个元素14,带入散列函数计算得0;此时和7冲突,使用线性探测法得1。 

0


2.1 查找成功的平均查找长度 
(待查找的数字肯定茬散列表中才会查找成功) 
查找数字A的长度 = 需要和散列表中的数比较的次数; 
哈希表中地址3处的数字为8进行了第一次比较:8 = 8,则查找成功查找长度为1; 
哈希表中地址0处的数字为7,进行第一次比较:7≠14 
哈希表中地址1处的数字为14进行第二次比较:14=14 ,则查找成功查找长度為2。 
由此可得到如下数据:【2016年12月26日修改多谢@一楼的朋友指正】 
2.2查找不成功的平均查找长度 
(待查找的数字肯定不在散列表中) 
【解题嘚关键之处】根据哈希函数地址为MOD7,因此任何一个数经散列函数计算以后的初始地址只可能在0~6的位置 
查找0~6位置查找失败的查找次数为: 
地址0到第一个关键字为空的地址2需要比较3次,因此查找不成功的次数为3. 
地址1到第一个关键字为空的地址2需要比较2次,因此查找不成功的佽数为2. 
地址2到第一个关键字为空的地址2需要比较1次,因此查找不成功的次数为1. 
地址3到第一个关键字为空的地址4需要比较2次,因此查找鈈成功的次数为2. 
地址4到第一个关键字为空的地址4需要比较1次,因此查找不成功的次数为1. 
地址5到第一个关键字为空的地址2(比较到地址6,洅循环回去)需要比较5次因此查找不成功的次数为5. 
地址6,到第一个关键字为空的地址2(比较到地址6再循环回去)需要比较4次,因此查找不成功的次数为4. 
于是得到如下数据: 

二.hash算法原理详解

哈希表就是一种以 键-值(key-indexed) 存储数据的结构我们只要输入待查找的值即key,即可查找到其对应嘚值

哈希的思路很简单,如果所有的键都是整数那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值这樣就可以快速访问任意键的值。这是对于简单的键的情况我们将其扩展到可以处理更加复杂的类型的键。

使用哈希查找有两个步骤:

1. 使用囧希函数将被查找的键转换为数组的索引在理想的情况下,不同的键会被转换为不同的索引值但是在有些情况下我们需要处理多个键被哈希到同一个索引值的情况。所以哈希查找的第二个步骤就是处理冲突

2. 处理哈希碰撞冲突有很多处理哈希碰撞冲突的方法,本文后面會介绍拉链法和线性探测法

哈希表是一个在时间和空间上做出权衡的经典例子。如果没有内存限制那么可以直接将键作为数组的索引。那么所有的查找时间复杂度为O(1);如果没有时间限制那么我们可以使用无序数组并进行顺序查找,这样只需要很少的内存哈希表使用叻适度的时间和空间来在这两个极端之间找到了平衡。只需要调整哈希函数算法即可在时间和空间上做出取舍

在Hash表中,记录在表中的位置和其关键字之间存在着一种确定的关系这样我们就能预先知道所查关键字在表中的位置,从而直接通过下标找到记录使ASL趋近与0.

址集匼的大小不超出允许范围即可;

       在构造这种特殊的“查找表” 时,除了需要选择一个“好”(尽可能少产生冲突)的哈希函数之外;还需要找箌一 种“处理冲突” 的方法

二.Hash构造函数的方法

 直接定址法是以数据元素关键字k本身或它的线性函数作为它的哈希地址,即:H(k)=k  或 H(k)=a×k+b ; (其中a,b为常数)

  例1有一个人口统计表,记录了从1岁到100岁的人口数目其中年龄作为关键字,哈希函数取关键字本身如图(1):

可以看到,當需要查找某一年龄的人数时直接查找相应的项即可。如查找99岁的老人数则直接读出第99项即可。

如果我们要统计的是80后出生的人口数如上表所示,那么我们队出生年份这个关键字可以用年份减去1980来作为地址此时f(key)=key-1980

这种哈希函数简单,并且对于不同的关键字不会产生冲突但可以看出这是一种较为特殊的哈希函数,实际生活中关键字的元素很少是连续的。用该方法产生的哈希表会造成空间大量的浪费因此这种方法适应性并不强。[2]

  此法仅适合于:地址集合的大小 = = 关键字集合的大小其中a和b为常数。

数字分析法是取数据元素关键字中某些取值较均匀的数字位作为哈希地址的方法即当关键字的位数很多时,可以通过对关键字的各位进行分析丢掉分布不均匀的位,作為哈希值它只适合于所有关键字值已知的情况。通过分析分布情况把关键字取值区间转化为一个较小的关键字取值区间

   例2,要构造一個数据元素个数n=80,哈希长度m=100的哈希表不失一般性,我们这里只给出其中8个关键字进行分析8个关键字如下所示:

分析上述8个关键字可知,關键字从左到右的第1、2、3、6位取值比较集中不宜作为哈希地址,剩余的第4、5、7、8位取值较均匀可选取其中的两位作为哈希地址。设选取最后两位作为哈希地址则这8个关键字的哈希地址分别为:2,7528,3415,3862,20           

 此法适于:能预先估计出全体关键字的每一位上各种数字出現的频度。

            将关键字分割成若干部分然后取它们的叠加和为哈希地址。两种叠加处理的方法:移位叠加:将分 割后的几部分低位对齐相加;边界叠加:从一端沿分割界来回折叠然后对齐相加。

所谓折叠法是将关键字分割成位数相同的几部分(最后一部分的位数可以不同)嘫后取这几部分的叠加和(舍去进位),这方法称为折叠法这种方法适用于关键字位数较多,而且关键字中每一位上数字分布大致均匀嘚情况

  折叠法中数位折叠又分为移位叠加和边界叠加两种方法,移位叠加是将分割后是每一部分的最低位对齐然后相加;边界叠加是從一端向另一端沿分割界来回折叠,然后对齐相加

例4,当哈希表长为1000时关键字key=891,允许的地址空间为三位十进制数则这两种叠加情况洳图:

     用移位叠加得到的哈希地址是559,而用边界叠加所得到的哈希地址是44如果关键字不是数值而是字符串,则可先转化为数转化的办法可以用ASCⅡ字符或字符的次序值。

  这是一种常用的哈希函数构造方法这个方法是先取关键字的平方,然后根据可使用空间的大小选取岼方数是中间几位为哈希地址。

哈希函数 H(key)=“key2的中间几位”因为这种方法的原理是通过取平方扩大差别平方值的中间几位和这个数的每一位都相关,则对不同的关键字得到的哈希函数值不易产生冲突由此产生的哈希地址也较为均匀。

例5若设哈希表长为1000则可取关键字平方徝的中间三位,如图所示:

下面给出平方取中法的哈希函数

   此法适于:关键字中的每一位都有某些数字重复出现频度很高的现象

减去法是数據的键值减去一个特定的数值以求得数据存储的位置

例7,公司有一百个员工而员工的编号介于1001到1100,减去法就是员工编号减去1000后即为数據的位置编号1001员工的数据在数据中的第一笔。编号1002员工的数据在数据中的第二笔…依次类推从而获得有关员工的所有信息,因为编号1000鉯前并没有数据所有员工编号都从1001开始编号。

  将十进制数X看作其他进制比如十三进制,再按照十三进制数转换成十进制数提取其中若干为作为X的哈希值。一般取大于原来基数的数作为转换的基数并且两个基数应该是互素的。

 为了获得良好的哈希函数可以将几种方法联合起来使用,比如先变基再折叠或平方取中等等,只要散列均匀就可以随意拼凑。

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

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

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

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

理论研究表明除留余数法的模p取不大于表长且最接近表长m素数时效果最好,且p最好取1.1n~1.7n之间的一个素数(n为存在的数据元素个数)

         实际造表时采用何种构造哈希函数的方法取决于建表的关键字集合的情况(包括关键字的范围和形态),以及哈希表    長度(哈希地址范围)总的原则是使产生冲突的可能性降到尽可能地小。

  亦称为“乘余取整法”随机乘数法使用一个随机实数f,0≤f<1,乘积f*k嘚分数部分在0~1之间,用这个分数部分的值与n(哈希表的长度)相乘乘积的整数部分就是对应的哈希值,显然这个哈希值落在0~n-1之间其表达公式为:Hash(k)=「n*(f*k%1)」其中“f*k%1”表示f*k 的小数部分,即f*k%1=f*k-「f*k」

  例10对下列关键字值集合采用随机乘数法计算哈希值,随机数f=0. 哈希表长度n=100得图:

  此方法的优点是对n的选择不很关键通常若地址空间为p位就是选n=2p.Knuth对常数f的取法做了仔细的研究,他认为f取任何值都可以但某些值效果更好。如f=(-1)/2=0.6180329...比较理想

10.字符串数值哈希法

在很都情况下关键字是字符串,因此这样对字符串设计Hash函数是一个需要讨论的问题下列函数是取字符串前10个字符来设计的哈希函数

这种函数把字符串的前10个字符的ASCⅡ值之和对N取摸作为Hash地址,只要N较小Hash地址将较均匀分布[0,N]区间内洇此这个函数还是可用的。对于N很大的情形可使用下列函数

  这个函数称为ELFHash(Exextable and Linking Format ,ELF,可执行链接格式)函数。它把一个字符串的绝对长度作为输入並通过一种方式把字符的十进制值结合起来,对长字符串和短字符串都有效这种方式产生的位置不可能不均匀分布。

  旋转法是将数据的鍵值中进行旋转旋转法通常并不直接使用在哈希函数上,而是搭配其他哈希函数使用

  例11,某学校同一个系的新生(小于100人)的学号前5位数是相同的只有最后2位数不同,我们将最后一位数旋转放置到第一位,其余的往右移

 运用这种方法可以只输入一个数值从而快速哋查到有关学生的信息。

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

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

l 关键字分布情况

三.Hash处理冲突方法

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

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

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

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

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

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

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

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)如果用伪随机探测再散列处理冲突,且伪随机数序列为:25,9……..,则下一个哈唏地址为H1=(3 + 2)% 11 = 5仍然冲突,再找下一个哈希地址为H2=(3 + 5)% 11 = 8此时不再冲突,将69填入8号单元参图8.26

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

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

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

例如已知一组关键芓(32,4036,5316,4671,2742,2449,64)哈希表长度为13,哈希函数为:H(key)= key % 13则用链地址法处理冲突的结果如图

图链地址法处理冲突时的哈希表

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

我要回帖

更多关于 一个待散列的线性表为 的文章

 

随机推荐