1023. 简单哈希2 哈希冲突的平方探测法


Description

 哈希表也称为散列表,它是通过关键码值而进行直接访问的数据结构。即它通过把一个关键码映射到表中的一个位置来访问记录,以加快查找速度。当然了在做关键码映射的时候,难免会把不同的关键码映射到相同的位置,这时冲突就产生了。使用平方探测法(Quadratic Probing)可以解决哈希中的冲突问题它的基本思想是:设hash函数为h(key) = d,并且假定其存储结构为循环数组,则当冲突发生时,它接下来需要探测的位置为h+1, h+4, h+9, ……, h+i^2,……直到冲突得到解决。

例如 现有关键码集为  {47 7 29 11 16 92 22 8 3}
设:哈希表表长为 m=11 ;哈希函数为 Hash(key)=key mod 11 ;采用平方探测法处理冲突。建哈希表如下:
 
0 1 2 3 4 5 6 7 8 9 10
11 22   47 92 16 3 7 29 8  
 
现在给定哈希函数为 Hash(key)= key mod m ,要求按照上述规则 使用 平方探测 法处理冲突的方法建立相应哈希表,并且处理以下操作。
Add a—— 表示 a(|a| <= 1000000000) 加入到 hash 表中。
Query a—— 表示查询 a 是否在 hash 表中
Pint—— 表示打印出当前的 hash 表状态
End—— 结束操作
Input

 输入的第一行为一个整数m1<m<=1000),表示hash表所用的数组的大小,同时也表示hash函数需要模的值,见题意描述。

接下来会有若干行,表示操作(如题所述),当输入为 End 时结束程序。
Output
对于每一个 Query a 操作,如果 a hash 表里面,输出 yes ,否则输出 no ,对于每一个 Print 函数,打印当前的 hash 表状态,格式为 idx#key ,其中 idx 表示数组下标, key 表示关键值,如果该位置没有关键值,则输出 NULL ,每个元素占一行,如对应于上面所述 hash 表,它的 Print 结果为
0#11
1#22
2#NULL
3#47
4#92
5#16
6#3
7#7
8#29
9#8

10#NULL 

Sample Input
 Copy sample input to clipboard
5
Add 1
Add 5
Add 6
Query 1
Query 7
Print
End
Sample Output
yes
no
0#5
1#1
2#6
3#NULL
4#NULL
#include<stdio.h>
#include <string.h>
#include<stdlib.h>
int main(){
int hash_len;
int j;
long long key[10000];
int hash[10000];
char op[10];
for(int i=0;i<10000;i++)
hash[i]=-1;
int query;
scanf("%d",&hash_len);
int jj=0;
while(1){
       scanf("%s",op);
       if(strcmp(op,"End")==0)
        break;
        if(strcmp(op,"Add")==0){
            scanf("%lld",&key[jj]);
            int h = key[jj]%hash_len;//哈希取模
            int conflic = 1;//用于解决冲突的计数器
            int ii=0;
            while(1){
                 if(hash[h]==-1) {//没有哈希地址冲突
                        hash[h] = key[jj];
                       break;
                }
                 else {
                h= h+conflic*conflic-ii*ii;
                if((h+conflic*conflic-ii*ii)>=hash_len){
                        h%=hash_len;//链表循环
                    }
                ii++;
                conflic++;
                 }
               
           }
       jj++;
        }
        if(strcmp(op,"Print")==0){
            for(int i=0;i<hash_len;i++){
               printf("%d",i);
               printf("#");
               if(hash[i]==-1)
                   printf("NULL\n");else
                   printf("%d\n",hash[i]);
            }
        }
        if(strcmp(op,"Query")==0){
            int exit=0;
            scanf("%d",&query);
            for(int i=0;i<hash_len;i++){
                if(hash[i]==query)
                    exit=1;
            }

                    if(exit)
                        printf("yes\n");
                else
                    printf("no\n");
            }
        }
return 0;
}                                 



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值