1145 Hashing - Average Search Time (25 分) 哈希表 平均查找长度

题干太长了,这次不写题干了,主要说说散列表,又叫哈希表(hash table)

散列表是一种存储数据的方法,通过散列表,可以实现直接用关键字(key)访问数据所在位置。具体实现方法为使用散列函数(哈希函数)H(key),对每个关键字,都可以计算出一个地址。显然,不同的关键字可能有同一个地址,造成地址冲突,有解决这些地址冲突的方法。

H(key)=address

哈希函数有很多种构造方法,常用的有除留余数法等,除留余数法如下,memory_size为分配的存储区域的容量。

H(key%memory_size)=address

其他方法也能将关键字转成对应地址。

如果两个不同键值计算出了相同的地址,就叫做发生了冲突,这些发生碰撞的不同关键字称为同义词,例如除留余数法,若memory_size=5,那么关键字6和11计算出的地址是相同的。

产生冲突,就需要就解决冲突的方法。解决冲突有两大类方法,一是开放定址法,二是链接法。

  • 开放定址法:定义很抽象,大意就是采用某种规则,发生冲突后,重新计算地址进行试探。设第i次冲突时下一个试探地址是Hi,则数学公式是Hi=(H(key)+di)%m。我们的目的是确定重新计算的规则,也就是确定di的取值,来不停地计算试探地址,直到找到不冲突的地址或者超过试探次数限制。常用的开放定址法有常用的开放定址法有平方探测法等。
    平方探测法:di=0,12,-12,22,-22,···,k2,-k2,k<=m/2.依次试探上述取值,直到找到空闲地址或者试探超过m+1次。

本题中就要使用平方探测法。

#include <bits/stdc++.h>
#define N 100000
using namespace std;

bool is_Prime(int n)    {
    if (n==1||n==0) return false;
    for (int i=2;i*i<=n;i++)
        if (n%i==0) return false;
    return true;
}
int ha[N];
int main()  {
    int s,n,m,ans=0;
    scanf("%d%d%d",&s,&n,&m);
    while (!is_Prime(s))    s++;
    for (int i=0;i<n;i++)  {
        int flag=0,t=0;
        scanf("%d",&t);
        for (int j=0;j<=s;j++)  {
            int key=(t+j*j)%s;
            if (ha[key]==0)   {
                ha[key]=t;
                flag=1;
                break;
            }
        }
        if (!flag)  printf("%d cannot be inserted.\n",t);
    }
    for (int i=0;i<m;i++)   {
        int t=0;
        scanf("%d",&t);
        for (int j=0;j<=s;j++)  {
            ans++;
            int tk=(t+j*j)%s;
            if (ha[tk]==t||ha[tk]==0)   break;
        }
    }
    printf("%.1f\n",1.0*ans/m);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值