整型关键字的散列映射
题目要求如下:
7-1 整型关键字的散列映射(25 分)
给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射到长度为P的散列表中。用线性探测法解决冲突。输入格式:
输入第一行首先给出两个正整数N(≤1000)和P(≥N的最小素数),分别为待插入的关键字总数、以及散列表的长度。第二行给出N个整型关键字。数字间以空格分隔。输出格式:
在一行内输出每个整型关键字在散列表中的位置。数字间以空格分隔,但行末尾不得有多余空格。输入样例:
4 5
24 15 61 88
输出样例:
4 0 1 3
哈希表(hash) :
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
除留余数法 :
取关键字转换为数字表示,然后用这个数余数组长度,这个结果用作数组的下标,便于访问。即 H(key) = key MOD p,p<=m。(MOD表示求余)
线性探测法:
若关键字得到的key值已经存在,那么依次往后走,直到找到一个空白的区域。
此题有个点需要注意,如果有一个关键字出现过了,那么输出它第一次出现时的位置,不重复存放相同的数据。
完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i, n, p, x, k;
scanf("%d %d", &n, &p);
int *s = (int *)malloc(sizeof(int)*p);
memset(s, 0, sizeof(int)*p); //初始化动态数组s[]
for(i = 0; i < n; i ++) {
scanf("%d", &x);
k = x % p;
if(s[k] == 0) { //如果此位置为空,直接存放
s[k] = x;
}
else { //否则
while(s[k] != 0 && s[k] != x) {
//依次往后寻找,直到找到空位,或者找到具有相同的值的数字
k = (k+1) % p;
}
if(s[k] != x) { //如果没有相等的,那么存储x
s[k] = x;
}
//否则,不用重复存储x
}
if(i == 0) {
printf("%d", k);
}
else {
printf(" %d", k);
}
}
return 0;
}