给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射到长度为P的散列表中。用线性探测法解决冲突。
输入格式:
输入第一行首先给出两个正整数N(≤1000)和P(≥N的最小素数),分别为待插入的关键字总数、以及散列表的长度。第二行给出N个整型关键字。数字间以空格分隔。
输出格式:
在一行内输出每个整型关键字在散列表中的位置。数字间以空格分隔,但行末尾不得有多余空格。
输入样例:
4 5
24 15 61 88
输出样例:
4 0 1 3
#include <stdio.h>
#include <string.h>
#define N 2000
typedef struct HashMap{
int loc;
int value;
} Hash;
int hash( int x, int p ) // 计算哈希值
{
return (x%p);
}
int main()
{
int n, p;
scanf("%d %d", &n, &p);
// flag[]用于标记地址是否已用,index[]用于按输入顺序记录地址
int flag[N], index[N];
int i, j;
/* 初始化两个数组的值为 0 */
memset(flag, 0, sizeof(flag));
memset(index, 0, sizeof(index));
int x;
Hash h[N];
for( i=0; i<n; i++)
{
scanf("%d", &x);
for( j=0; j<i; j++)
{
if( x == h[j].value ) // 查询是否重复
{
index[i] = h[j].loc;
break;
}
}
if( j==i ) // 查找存入的地址值
{
int h0 = hash(x, p);
int cnt = 0;
int hi = hash(h0, p);
while( cnt != p && flag[hi] ) // 冲突,寻找新的地址
{
h0 ++;
cnt ++;
// 由于答案中的地址区间是在 [0, p],所以超过 p时要回到头部
hi = hash(h0, p); // 寻找新的地址
}
flag[hi] = 1; // 标记该地址已使用
index[i] = hi; // 记录地址值
h[i].value = x;
h[i].loc = hi;
}
}
for(i=0; i<n; i++) { // 遍历输出地址值
if(i != (n-1))
printf("%d ", index[i]);
else
printf("%d", index[i]);
}
return 0;
}