实例要求:编程实现哈希查找。具体要求如下:
哈希表长度为11,哈希函数为H(key)%11,随机产生待散列的小于50的8个元素,同时采用线性探测再散列的方法处理冲突。具体效果如下图:
实现步骤
1.引用头文件,进行宏定义声明全局变量
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define Max 11
#define N 8
int hashtable[Max];
2.自定义函数func(),用于返回哈希函数的值
int func(int value)
{
return value % Max; /*哈希函数,这里采用余数法*/
}
3.自定义函数search(),用于实现哈希查找
int search(int key) /*自定义函数实现哈希查询*/
{
int pos, t;
pos = func(key); /*哈希函数确定出的位置*/
t = pos; /*t存放确定出的位置*/
while (hashtable[t] != key && hashtable[t] != - 1)
/*如果该位置上不等于要查找的关键字且不为空*/
{
t = (t + 1) % Max; /*利用线性探测求出下一个位置*/
if (pos == t)
/*如果经多次探测又回到原来用哈希函数求出的位置则说明要查找的数不存在*/
return - 1;
}
if (hashtable[t] == - 1)
/*如果探测的位置是-1则说明要查找的数不存在*/
return NULL;
else
return t;
}
4.自定义函数creatHash(),用于实现哈希表的创建
void creathash(int key) /*自定义函数创建哈希表*/
{
int pos, t;
pos = func(key); /*哈希函数确定元素的位置*/
t = pos;
while (hashtable[t] != - 1)
/*如果该位置有元素存在则进行线性探测再散列*/
{
t = (t + 1) % Max;
if (pos == t)
/*如果冲突处理后确定的位置与原位置相同则说明哈希表已满*/
{
printf("哈希表已满\n");
return ;
}
}
hashtable[t] = key; /*将元素放入确定的位置*/
}
5.main()函数作为程序的入口函数
void main()
{
int flag[50];
int i, j, t;
for (i = 0; i < Max; i++)
hashtable[i] = - 1;
/*哈希表中初始位置全置-1*/
for (i = 0; i < 50; i++)
flag[i] = 0;
/*50以内所有数未产生时均标志为0*/
srand((unsigned long)time(0)); /*利用系统时间做种子产生随机数*/
i = 0;
while (i != N)
{
t = rand() % 50; /*产生一个50以内的随机数赋给t*/
if (flag[t] == 0)
/*查看t是否产生过*/
{
creathash(t); /*调用函数创建哈希表*/
printf("%2d:", t); /*将该元素输出*/
for (j = 0; j < Max; j++)
printf("(%2d) ", hashtable[j]);
/*输出哈希表中内容*/
printf("\n");
flag[t] = 1; /*将产生的这个数标志为1*/
i++; /*i自加*/
}
}
printf("请输入你想查找的元素:");
scanf("%d", &t); /*输入要查找的元素*/
if (t > 0 && t < 50)
{
i = search(t); /*调用search进行哈希查找*/
if (i != - 1)
printf("查找成功!其位置是:%d\n", i);
/*若查找到该元素则输出其位置*/
else
printf("查找失败!");
/*未找到输出提示信息*/
}
else
printf("输入有误!");
}
注意:1.本案例采用的哈希函数构造方法为余数法,也是大学教案中常用的方法
2.虽然构造好的哈希函数可以减少冲突, 但是冲突仍不可避免。所产生相应的避免哈希冲突的方法共有四种:开放定址法,链地址法,再哈希及建立公共溢出区法。各位可以根据自身需要对代码进行二次优化 本篇运用开放定址法中的线性探测再散列