我们要首先知道哈希表是干什么的,哈希表并不是为了单纯存储数据的,他并不会减小存储这些数据使用的空间,而是为了实现快速的数据查找,插入和删除操作。map就可以使用哈希表来实现,所以map可以实现利用键来快速访问到值。
哈希表是一种数据结构,它通过使用哈希函数将关键字映射到内存中的特定位置(通常是数组的索引),从而将关键字和其存储的地址之间建立了联系。这样一来,当需要查找特定关键字时,可以通过哈希函数计算出其在哈希表中的位置,并直接访问该位置的存储单元,从而实现快速的查找操作。
哈希函数在构造哈希表的时候就是运用关键字来构造的,这样才能决定我们访问哈西表中的关键字十分迅速,对于普通数组只是将各种关键字仅仅存储了进去,没有根据关键字来存储,所以这样访问关键字的位置就很慢。顺便说一下这里的关键字就是数据库中的关键字,是主键,能唯一标识一条数据,所以这个属性中的值不能重复,有点扯远了。
下面着重来讲解的是,使用哈希冲突解决方法:线性探测再散列和二次探测再散列,来构建哈希表之后,如何求查找成功和查找失败的平均查找长度。
哈希表的查找过程其实与构造过程相同
当我们在哈希表中查找时,查找过程的顺序必须与构造哈希表时采用的哈希冲突处理方式的顺序相同。这是因为哈希表的查找依赖于哈希函数和哈希冲突处理方式。如果查找过程不遵循构造哈希表时采用的哈希冲突处理方式的顺序,就可能无法正确查找数据,导致查找结果错误或异常。正确的顺序确保查找与插入/删除过程保持一致,从而保证哈希表的完整性和一致性。
下面这个例子使用的哈希冲突解决方法为:开放寻址法中的线性探测再散列
关键字集合{45,18,33,5,78,66,21,19,11,32}
m=13 n=10 p=11 哈希函数 H(key)=key mod 11
这个哈希表我们已经构造完成了
- 求成功的ASL是针对于每个数字的,即你要把所有数字的查找后的次数做个累加,最后除的数字是元素的个数!这个很好理解,因为我们研究的也是所有元素的查找次数。
- 主要介绍求失败的ASL
对于一个元素如14
查找流程 14%11=3 H1 = ( 3 + 1 ) mod 13 = 4 H2 = 5 H3 = 6
在下标6位置发现元素为空,说明查找不成功。为什么?
前面说了查找过程与创建哈希表过程一样。创建时若这个为空,肯会将14填入位置6,现在查找时发现为空只能说明当初创建时没有14这个元素,故14不在哈希表中,查找失败。
这样我们便不难理解,对于查找一个元素e时,会看先看e%P,便对应等可能性定位到P个地址上,我们便数这个位置距离最近的空位有多远(这里是以线性探测再散列为例)
我们查找失败时,对于一个元素初始%P等可能定位至P个位置,分母故为P,分子为每个位置到最近空的位置比较的次数和。
这里的ASL=(7+6+5+4+3+2+1+3+2+1+3)/11 = 37/11
求不成功的ASL针对的是每个位置!即每个位置往后找第一个为空的位置所比较的次数,然后累加最后除以哈希表的规模(如果是除留余数法,这个规模就是那个模数),使用除留余数法构造的位置的个数为p。
使用二次探测再散列解决哈希冲突,我们求平均查找长度
查找过程的顺序必须与构造哈希表时采用的哈希冲突处理方式的顺序相同
所以这里查找的时候要按照增量序列:di:1^2,-1^2,2^2,-2^2,3^2,-3^2 ……
即1,-1,4,-4,9,-9……来查找,当然生成哈希表的时候解决冲突也是按照这个序列来解决的,因为哈希表的查找过程其实与构造过程相同
例子就以图片形式了,这里我能保证哈希表构造是正确的,但是这两个平均查找长度我就不确定了,很可能是错误的,所以,欢迎大家指正!!!