题目内容
- 输入关键字序列;
- 用除留余数法构建哈希函数,用线性探测法(线性探测再散列)解决冲突,构建哈希表(在插入关键字时,由于已经默认了插入的关键字互不相同,没有判断哈希表中是否已经存在该关键字);
- 对哈希表计算在等概率情况下查找失败时的平均次数;
- 在哈希表中查找给定的关键字,给出查找次数。
输入输出样例
关键字个数 n,关键字 key(这里我们认为关键字 key就是哈希表中元素对应的哈希函数值),和除留余数法中的 p。要求按顺序输入关键字后,输出哈希表的相关信息。
源代码
#include<iostream>
using namespace std;
#define MAXNUM 500
typedef struct{
int Address[MAXNUM];//哈希表地址
int Keyword[MAXNUM];//哈希表关键字
int keynum;//关键字个数
int SuccessFind[MAXNUM]={0};//成功查找次数
int FailFind[MAXNUM]={0};//失败查找次数
float AveSuccess=0;//查找成功的平均查找次数
float AveFail=0;//查找失败时在各个位置上的平均查找次数
}HashTable;
int p=1;//除留余数法中的除数
int Hash(int);//哈希函数(除留余数法)
void InsertHash1(HashTable*,int);//线性探测再散列把关键字插入哈希表
void SearchHash1(HashTable*,int);//在哈希表中查找关键字
void JudgeFail1(HashTable*);//求在每个地址查找失败时的最小散列次数
主函数
int main(){
int i,key[MAXNUM];
HashTable *hashtable = new HashTable;
cout<<"请依次输入关键字个数、关键字和除留余数法中的除数"<<endl;
cin>>hashtable->keynum;
for(i=0;i<hashtable->keynum;i++)
cin>>key[i];
cin>>p;
for(i=0;i<p;i++){
hashtable->Address[i]=i;
hashtable->Keyword[i]=-1;//初始化哈希表中没有关键字的位置为-1
}
cout<<"哈希表地址:";
for(i=0;i<p;i++)
cout<<hashtable->Address[i]<<" ";
cout<<endl;
for(i=0;i<hashtable->keynum;i++)
InsertHash1(hashtable,key[i]);
cout<<"表中关键字:";
for(i=0;i<p;i++)
if(hashtable->Keyword[i]!=-1)
cout<<i<<":"<<hashtable->Keyword[i]<<" ";
cout<<endl;
for(i=0;i<hashtable->keynum;i++)
SearchHash1(hashtable,key[i]);
cout<<"成功查找次数:";
for(i=0;i<p;i++){
cout<<i<<":"<<hashtable->SuccessFind[i]<<" ";
hashtable->AveSuccess+=hashtable->SuccessFind[i];
}
cout<<endl;
JudgeFail1(hashtable);//求在每个地址查找失败时的最小散列次数
cout<<"失败查找次数:";
for(i=0;i<p;i++){
cout<<i<<":"<<hashtable->FailFind[i]<<" ";
hashtable->AveFail+=hashtable->FailFind[i];
}
cout<<endl;
cout<<"查找成功的平均查找次数:"<<hashtable->AveSuccess/hashtable->keynum<<endl;
cout<<"查找失败的平均查找次数:"<<hashtable->AveFail/p<<endl;
delete hashtable;
}
哈希函数
int Hash(int m){//哈希函数(除留余数法)
return m%p;
}
把关键字插入哈希表
void InsertHash1(HashTable* H,int key){//线性探测再散列把关键字插入哈希表
int address=Hash(key);
while (H->Keyword[address]!=-1)
address=(address+1)%p;//线性探测再散列
H->Keyword[address]=key;
}
在哈希表中查找关键字
void SearchHash1(HashTable* H,int key){//在哈希表中查找关键字
int address=Hash(key),num=0;
while (H->Keyword[address]!=key){
num++;
address=(address+1)%p;
if(H->Keyword[address]==-1||address==Hash(key)){//假如查找到一个没有关键字的位置或者查找了一圈回到原来的位置,说明哈希表中没有该关键字
cout<<"哈希表中没有该关键字"<<endl;
break;
}
}
H->SuccessFind[address]=++num;
}
求在每个地址查找失败时的最小散列次数
void JudgeFail1(HashTable* H){//求在每个地址查找失败时的最小散列次数
int i,temp;
for(i=0;i<p;i++){
H->FailFind[i]++;
temp=i;
while (H->Keyword[temp]!=-1){
temp=(temp+1)%p;
if(H->Keyword[temp]!=H->Keyword[i])
H->FailFind[i]++;
else{
H->FailFind[i]++;
break;
}
}
}
}