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
输入的第一行为一个整数m(1<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
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; }