目录
题目描述
定义哈希函数为H(key) = key%11。输入表长(大于、等于11),输入关键字集合,用二次探测再散列构建哈希表,并查找给定关键字。
输入
测试次数t
每组测试数据格式如下:
哈希表长m、关键字个数n
n个关键字
查找次数k
k个待查关键字
输出
对每组测试数据,输出以下信息:
构造的哈希表信息,数组中没有关键字的位置输出NULL
对k个待查关键字,分别输出:
0或1(0—不成功,1—成功)、比较次数、查找成功的位置(从1开始)
输入样例
1
12 10
22 19 21 8 9 30 33 4 41 13
4
22
15
30
41
输出样例
22 9 13 NULL 4 41 NULL 30 19 8 21 33
1 1 1
0 3
1 3 8
1 6 6
思路分析
这道题考察的是哈希表的二次探测,用哈希函数算出数据本该放的地址,如果该地址已经被占了,那就 地址=(地址+di)%11;di就是你要加的那个序列,di=1^2,-1^2,2^2,-2^2,3^2,-3^2......就是二次序列,题目是用二次探测。思路:设一个visited数组,来标志这个位置有没有数据,初始为0,若已有数据就设为1。先用哈希函数算出数据本该放的地址,若visited==0,直接放进去,并把visited置为1。若visited==1,就更新坐标,直到找到visited==1的地方,再填入,置visited为1。
AC代码
#include<iostream>
using namespace std;
int hashh(int key){
return key%11;
}
int main(){
int t,m,n,k;
cin>>t;
while(t--){
int key,d;
cin>>m>>n;
int a[m]={0};
int visited[m]={0};
while(n--){
cin>>key;
int sum=0;
int index=hashh(key);
while(visited[index]==1){
if(sum%2==0) d=(sum/2+1)*(sum/2+1);
else d=-1*(sum/2+1)*(sum/2+1);
index=(hashh(key)+d)%m;
if(index<0) index+=m;
sum++;
}
// cout<<"index="<<index<<"时,值为"<<key<<endl;
a[index]=key;
visited[index]=1;
}
for(int i=0;i<m-1;i++){
if(a[i]!=0) cout<<a[i];
else cout<<"NULL";
cout<<" ";
}
if(a[m-1]==0) cout<<"NULL"<<endl;
else cout<<a[m-1]<<endl;
cin>>k;
while(k--){
int sum=0;
cin>>key;
int i=hashh(key);
int tag;
while(1){
if(a[i]==key) {
tag=1;
break;
}
else if(a[i]==0){
tag=0;
break;
}
else ;
if(sum%2==0) d=(sum/2+1)*(sum/2+1);
else d=-1*(sum/2+1)*(sum/2+1);
i=(hashh(key)+d)%m;
sum++;
}
if(tag==1) cout<<"1 "<<sum+1<<" "<<i+1<<endl;
else cout<<"0 "<<sum+1<<endl;;
}
}
return 0;
}