1145 Hashing - Average Search Time

题意:哈希映射,利用平方探测法解决冲突,并计算平均查找时间。

思路:首先,需掌握什么是平方探测法(Quadratic probing)。所谓平方探测法,即当H(key)发生冲突时,让key按key+1^2,key-1^2,key+2^2,key-2^2......的顺序进行调整,而题目中说明只需要往正方向解决冲突,即解决冲突的函数为H(key)=(key+d^2)%TSize,d=0,1,2,...TSize-1,其中TSize为哈希表的表长。其次,需掌握如何计算平均查找时间,所谓平均查找时间,就是每个查询值的比较次数之和除以查询个数,下面以样例进行说明,下表为建立好的哈希表。

hashtable[i]10611 4
i0         1       2       3       4       

(1).当查询值key=11时,H(11)=11%5=1,发现hashtable[1]≠11(第1次比较),即发生冲突,继续查找;

            H(11)=(11+1^2)%5=2,此时hashtable[2]==11(第2次比较),查找成功,共查找了2次。

(2).当查询值key=4时,H(4)=4%5=4,发现hashtable[4]==4(第1次比较),查找成功,共查找了1次。

(3).当查询值key=15时,H(15)=15%5=0,发现hashtable[0]≠15(第1次比较),即发生冲突,继续查找;

             H(15)=(15+1^2)%5=1,此时hashtable[1]≠15(第2次比较),发生冲突,继续查找;

             H(15)=(15+2^2)%5=4,此时hashtable[4]≠15(第3次比较),发生冲突,继续查找;

             H(15)=(15+3^2)%5=4,此时hashtable[4]≠15(第4次比较),发生冲突,继续查找;

             H(15)=(15+4^2)%5=1,此时hashtable[1]≠15(第5次比较),还是发生冲突,此时正向偏移d已经等于TSize-1,故不用再继续查询了,说明key=15查询失败,它总共查找了5次。——但是,若key值在d从0~TSize-1进行枚举后仍然无法解决冲突,PAT里在这种情况下要多加1次,也就是认为key=15总共比较了6次!!!还没搞明白!!!

(4).当查询值key=2时,H(2)=2%5=2,发现hashtable[2]≠2(第1次比较),即发生冲突,继续查找;

           H(2)=(2+1^2)%5=2,此时hashtable[2]为空(第2次比较),说明这个值不在表中,故查找结束,共查找了2次。

因此,平均查找时间为(2+1+6+2)/4≈2.8

代码:

#include <cstdio>
#include <cmath>
#include <cstring>

const int N=10005;
int hashtable[N]={0};

bool isPrime(int n)
{
    if(n<=1) return false;
    int sqr=(int)sqrt(n);
    for(int i=2;i<=sqr;i++)
        if(n%i==0) return false;
    return true;
}

int main()
{
    int MSize,n,queryCnt,key;
    scanf("%d%d%d",&MSize,&n,&queryCnt);
    while(!isPrime(MSize)) 
        MSize++;
    while(n--){
        scanf("%d",&key);
        int d=0;
        for(;d<MSize;d++){
            int p=(key+d*d)%MSize;
            if(hashtable[p]==0){
                hashtable[p]=key;
                break;
            }
        }
        if(d==MSize) printf("%d cannot be inserted.\n",key);
    }

    int tot=0;//总的查询次数
    int tmp=queryCnt;
    while(tmp--){
        scanf("%d",&key);
        int d=0;
        int cnt=0;//key值的查询次数
        for(;d<MSize;d++){
            int p=(key+d*d)%MSize;
            cnt++;
            if(hashtable[p]==0 || hashtable[p]==key)
                break;//遇到空位置或找到对应的值
        }
        if(d==MSize) cnt++;//注意特殊情况,对应上述查询key=15
        tot+=cnt;
    }
    printf("%.1f",1.0*tot/queryCnt);
    return 0;
}

 

转载于:https://www.cnblogs.com/kkmjy/p/9550541.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值