题目描述
采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用开放定址法的线性探测。
输入
第一行为哈希表的长度n; 第二行为关键字的个数; 第三行为关键字集合; 第三行为要查找的数据
输出
如果查找成功,输出关键字所哈希表中的地址和比较次数;如果查找不成功,输出-1。
样例输入
13
11
16 74 60 43 54 90 46 31 29 88 77
16
样例输出
3,1
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define MaxSize 1000
#define NULLKEY -1//哈希表中空闲单元关键字
#define DELKEY -2//哈希表中被删除的关键字
typedef struct
{
int key;//键值
int counts;//探测次数
}HashTable;
HashTable ha[MaxSize];
int keys[MaxSize];
void Insert(HashTable ha[],int n,int key)
{
//ha是哈希表,n是哈希表长度,key是当前要插入的关键字
int i,adr;
adr=key%n;//通过除留取余法求地址
if(ha[adr].key==NULLKEY||ha[adr].key==DELKEY)
{
//如果地址所在哈希表为空或为被删除键值
//则用新数据key覆盖旧数据
ha[adr].key=key;
ha[adr].counts=1;
}else
{
i=1;//查找次数
do
{
adr=(adr+1)%n;
i++;
}while(ha[adr].key!=NULLKEY&&ha[adr].key!=DELKEY);
//循环查找哈希表,直到某个关键字为空或为被删除键值
ha[adr].key=key;
//找到后设置键值
ha[adr].counts=i;
//设置查找次数
}
}
void Create(HashTable ha[],int n,int m,int keys[])
{
//n表示哈希表长度,ha是哈希表,keys是键值数组
//m是键值长度
for(int i=0;i<n;i++)
{
ha[i].key=NULLKEY;
//初始化哈希表键值为空
ha[i].counts=0;
//初始化哈希表的探测次数为0
}
for(int i=0;i<m;i++)//把m个键值插入哈希表
{
Insert(ha,n,keys[i]);
}
}
void Seek(HashTable ha[],int n,int keynumer)
{
int i=1,adr;
//比较次数和地址
adr=keynumer%n;//除留取余法求地址
while(ha[adr].key!=NULLKEY&&ha[adr].key!=keynumer)
{
//循环查找哈希表,看是否有关键字
i++;
adr=(adr+1)%n;
}
if(ha[adr].key==keynumer)//关键字
{
printf("%d,%d",adr,i);
}else//无
{
printf("-1");
}
}
int main()
{
int n,m,keynumber;
scanf("%d",&n);//哈希表的长度
scanf("%d",&m);//键值长度
for(int i=0;i<m;i++)
{
scanf("%d",&keys[i]);
}
Create(ha,n,m,keys);
scanf("%d",&keynumber);//关键字
Seek(ha,n,keynumber);
}