B. DS哈希查找—二次探测再散列

目录

题目描述

思路分析

AC代码


题目描述

定义哈希函数为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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值