哈希表(散列表)的平均查找成功/失败长度

计算哈希地址的方法,称之为哈希函数。
常见的计算哈希地址方法有:
1、直接定址法
2、除留余数法
3、数字分析法
4、平方取中法

本文所分析的是使用除留余数法计算哈希地址这类,的平均查找成功长度和查找失败长度


对于除留余数法的哈希函数(散列函数)
H(key) = key % p(n)
p(n)为不超过表长的最大素数。

如何计算平均查找/失败长度?
哈希表可以使用闭散列(开放定址法),也可以使用开散列(拉链法,哈希桶)进行构造。目前我在哈希中所遇到过的让计算平均查找成功/失败长度的情况,只有使用闭散列的线性探测构造的散列表 和 拉链法构造的散列表。


拉链法构造的散列表

查找成功的平均查找长度(拉链法)

计算查找成功的平均查找长度的前提,是查找成功,意味着能够在当前的散列表中找到。

查找到每一个位置上的概率为 1/总数据元素个数

查找了1层就查找成功概率P1为:
(1 / 总数据元素个数 )* 第一层的数据元素个数
查找了2层就查找成功的概率P2:
(1 / 总数据元素个数)* 第2层的数据元素个数

查找了n层长度的查找成功的概率Pn为:(1 / 总数据元素个数)* 第n层的数据元素个数

查找成功的平均查找长度 = P1 * 1 + P2 * 2 + P3 *2 + … + Pn * n

例如:
在这里插入图片描述
一共有11个数据元素,查找成功一定会找到这11个数据元素的位置上,那么落在这些位置上的概率都是1/11。
第一层有7个数据元素,所以找一层就找到了的概率为7 / 11
第二层有2个数据元素,所以找二层就找到了的概率为2 / 11

根据数学期望的知识
可知查找成功的平均查找长度ASL = 7/11 * 1 + 2/11 * 2 + 1/11 * 3 + 1/11 * 4 = 18/11

查找失败的平均查找长度(拉链法)

计算查找失败的平均查找长度的前提,是查找失败,意味着我们查找的位置一定落在没有数据的位置上。注意:查找到0层,意味着通过计算的哈希地址去找,这个哈希地址下根本没有数据元素。
查找了0层就查找失败的概率P0:(1 / 查找失败可能落在的位置总个数)* 第0层的查找失败可能落在的位置个数
查找了1层就查找失败的概率P1:(1 / 查找失败可能落在的位置总个数)* 第1层的查找失败可能落在的位置个数
查找了2层就查找失败的概率P2:(1 / 查找失败可能落在的位置总个数)* 第2层的查找失败可能落在的位置个数

查找了n层就查找失败的概率Pn:(1 / 查找失败可能落在的位置总个数)* 第n层的查找失败可能落在的位置个数。

查找失败的平均查找长度 = P0*0 + P1 * 1 + P2 * 2 + P3 *2 + … + Pn * n

例如:
在这里插入图片描述
当我们按照规则去查找的时候,找到下面红色圈圈标起来的位置时,就说明要找的数据不在散列表中,所以上图查找失败可能落在的位置总个数为13。那么在查找失败的前提下,落在圈起来的位置上的每一个概率都是1/13
在这里插入图片描述
当我们计算出来的哈希位置,根本没有数据,压根不需要找就知道它不在 ===> 查找0层就查找失败了。
此例中查找了0层就查找失败的概率P0 = 6 * (1 / 13) = 6/13

在这里插入图片描述
查找了1层就查找失败的概率P1 = 5* (1 / 13) = 5/13
在这里插入图片描述
查找了2层就查找失败的概率P1 = 1* (1 / 13) = 1/13
在这里插入图片描述
查找了4层就查找失败的概率P1 = 1* (1 / 13) = 1/13
在这里插入图片描述
所以查找失败的平均查找长度ASL = 6/13 * 0 + 5/13 * 1 + 1/132 + 1/134 = 11/13

线性探测构造的散列表

使用线性探测来构造散列表,首先使用哈希函数计算出哈希地址后,如果出现哈希冲突,那么依次向后去寻求一个空位置来存放。

查找失败的查找平均长度(线性探测)

注意:查找失败的情况,不是根据哈希表中实际存储的有效数据个数,也不是根据哈希表的长度来计算的。

计算查找失败的平均长度取决于
1.哈希函数
2.空位置

为什么?为了不那么晦涩,我使用实际的例子进行说明。(这里的空位置就是没有保存数据,没有被标记删除)
在这里插入图片描述
回顾线性探测,哈希的查找过程:首先使用哈希函数计算出哈希地址,从哈希地址开始进行查找,如果当前不存在则向后依次去查找,一直到查找到正确位置或者找到了空位置为止,而找到空位置时也说明了我们要查找的数据元素根本不在该哈希表内。

假设我们给出的哈希函数是H(key) = (key*3)%7
对于一个数去%7,算出来的值不会超过7,故而查找时计算出的哈希地址只可能是0、1、2、3、4、5、6

假设我们要查找一个关键字m,计算出的哈希地址为0,
1.先去探测哈希地址0,发现不是,
2.去探测哈希地址1,发现不是
2.去探测哈希地址2,发现是空位置
发现是空的,说明查找失败了
在这里插入图片描述
因此计算出的哈希地址为0的关键字,在该哈希表中查找失败的长度为3
同理,计算出的哈希地址为1的关键字,在该哈希表中查找失败的长度为2
在这里插入图片描述
计算出的哈希地址为2的关键字,在该哈希表中查找失败的长度为1
在这里插入图片描述
计算出的哈希地址为3的关键字,在该哈希表中查找失败的长度为2
在这里插入图片描述

根据上述的推导过程,我们就可以得出查找失败的所有情况。
在这里插入图片描述
故而,查找失败的情况只取决于哈希函数和空位置。
而对于一个需要查找的关键字,在还不知道具体数值的情况下,我们认为它计算出来的哈希地址落在每一个地址(0~6)的概率都相同,即1/7

根据数学期望的知识,可知查找失败的平均查找长度为:
ASL = 3*(1/7)+ 2*(1/7)+1*(1/7)+2*(1/7)+1*(1/7)+5*(1/7)+4*(1/7)=18/7

查找成功的查找平均长度(线性探测)

查找成功,说明我们要找的关键字一定是该哈希表中已经存在的。
在这里插入图片描述
该哈希表中一共有7个有效数据元素,那么在等概率情况下和查找成功的前提下,落在每一个有效数据位置的概率为1/7.假设我们给出的哈希函数是H(key) = (key*3)%7

如果我们查找的是7,7的哈希地址是(7*3)%7= 0,从哈希地址0开始探测,探测一次,就找到了
如果我们查找的是14,14的哈希地址是0,从哈希地址0开始探测
1.探测哈希地址0,发现不是
2.探测哈希地址1,发现是
所以查找14的探测(查找)长度为2

根据上述的推导过程,我们就可以得出查找成功的所有情况。
在这里插入图片描述
而查找成功的前提下,并且等概率的情况下,查找的是其中某一个关键字的概率是1/7
根据数学期望的知识,可以得出:
查找成功的平均查找长度ASL=1*(1/7)+2*(1/7)+1*(1/7)+1*(1/7)+1*(1/7)+3*(1/7)+3*(1/7)= 12/7

  • 59
    点赞
  • 310
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
### 回答1: 创建哈希表时,可以采用拉链法来解决冲突,即将哈希值相同的元素存储在同一个链表中。构造散列表时,需要确定哈希函数和哈希表的大小。哈希函数可以根据具体的需求来设计,而哈希表的大小应该足够大,以避免冲突的发生。 在使用哈希表进行查找时,需要先计算出要查找的元素的哈希值,然后在对应的链表中进行查找。如果链表中存在该元素,则查找成功;否则,需要继续查找下一个元素,直到找到或者遍历完整个链表。 平均查找长度是指在哈希表查找一个元素时,需要遍历的平均链表长度。它可以通过统计哈希表中所有链表的长度,并计算平均值来得到。平均查找长度越小,哈希表的性能就越好。 ### 回答2: 散列表(HashTable)即哈希表,是一种通过关键码值直接进行访问的数据结构,也称为散列设计、哈希散列和数字散列。在构造哈希表时,可能存在不同的关键字映射到同一个位置(即冲突),为了解决这种冲突,常用的方法是拉链法。 拉链法是一种解决哈希表冲突的常用方式。在这种方法中,将散列表的每个位置上设置一个链表(或者其他的数据结构),当发生哈希冲突时,就将数据插入到相应位置的链表中。具体操作过程如下: 1.创建一个基于拉链法的哈希表。 2.确定哈希表的大小,将一个含有n个元素的集合映射到大小为m的哈希表中,通常情况下,m > n,选择质数可以降低冲突的可能性。 3.对于给定的键,计算哈希函数,得到该键对应的哈希桶的位置,并将该键值插入到这个桶中。 4.如果不同的元素的哈希函数值相同,则在该桶中进行链式存储。 5.当需要查找一个元素时,首先通过哈希函数得到它在哈希表中的位置,然后在对应的链表上进行查找。 通过拉链法解决冲突的散列表,其平均查找长度的计算公式为ASL=α+(1-α)*(1+1/2+1/3+...+1/1-k),其中,ASL为平均查找长度,α表示散列表中填入元素的个数与散列表长度n的比值,k表示散列表中链表的长度。 在哈希表的创建和哈希函数计算中,需要注意哈希函数的设计,使得映射到哈希表中的散列桶分布均匀,减少哈希冲突的可能性。同时,在确定散列表大小时,选择足够大的大小也可以有效减少哈希冲突的发生。 总之,拉链法是一种常用的哈希表冲突解决方法,能够有效提高哈希表的查询效率和存储效率,对于大规模的数据处理和查找操作,使用哈希表可大幅提高程序的性能。 ### 回答3: 哈希表是一种数据结构,它可以将任意长度的数据映射成固定长度的数据,这个映射规则称为哈希函数。哈希函数通常将数据映射到一系列整数值中的一个,这个整数值就是数据的哈希地址。哈希表的结构非常适合用于实现查找表,因为它可以在常数时间内查找和插入元素,也就是说,这两个操作的时间复杂度是O(1)。 拉链法是一种解决哈希冲突的方法,它的基本思路是将哈希表中的每个槽存储成一个链表,如果多个元素的哈希地址落在同一个槽上,就将它们放到这个槽对应的链表中。这样,每个元素可以通过对应的哈希地址找到自己所在的槽,然后再在链表中查找。如果使用这种方法,哈希表的时间复杂度就会增加,因为查找一个元素的平均时间会变为O(1+m/n),其中m是哈希表的大小,n是元素的数量。但是,实际上,在一般情况下,m可以很大,因此,m/n的值通常很小,所以平均查找长度仍然很短。 要创建一个哈希表,首先需要选择一个合适的哈希函数,然后确定哈希表的大小,接下来就可以开始构造哈希表了。 例如,我们要创建一个大小为10的哈希表,使用一种简单的哈希函数,就是将元素的值除以10,然后取余,这样就可以将任意整数映射到0-9之间的一个整数中。然后,我们就可以将哈希表中的每个槽都初始化为空链表。如果要插入一个元素,就将它的哈希地址计算出来,然后将它放入对应的链表中。如果要查找一个元素,就计算它的哈希地址,并在对应的链表中查找,直到找到该元素或者链表为空为止。 如果要输出平均查找长度,即每次查找平均次数,可以定义一个计数器,每次查找操作都将计数器加1,最后除以元素的总数即可。假设我们有n个元素,哈希表大小为m,每个链表的平均长度为k,则平均查找长度为(n/m)*k。这个值的大小与哈希函数的选择、哈希表的大小、元素的数量和哈希冲突的解决方法等多方面因素有关。因此,在设计哈希表时,需要根据实际需求进行合理的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小酥诶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值