1.实验题目
针对某个集体中人名设计一个哈希表,使得平均查找长度不超过 R,并完成相应的建表和查表程序。假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有 30 个,取平均查找 长度的上限为 哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突。
2.需求分析
需将姓名拼音转化为数字才能比较
哈希表冲突后的探测使用线性探测法
采用数组形式进行存储
3.概要设计
存储数据包括 拼音 地址 查找次数,查找长度
哈希表的存储过程
根据关键字查找
函数的调用
#define NAME_NO 30
#define HASH_LENGTH 50
#define M 50
typedef struct
{
char *py;
int k;
}NAME;
typedef struct
{
char *py;
int k;
int si;
}HASH;
NAME NameList[30];
HASH HashList[HASH_LENGTH];
4:主要算法设计
(1)姓名(结构体数组)初始化
名字以拼音的形式够成字符串,将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字。
void init_namelist()
{
int i;
int j;
int s0;
char *p;
NameList[0].py="chenliang";//陈亮
NameList[1].py="chenyuanhao";//陈元浩
NameList[2].py="chengwenliang";//程文亮
NameList[3].py="dinglei";//丁磊
NameList[4].py="fenghanzao";//冯汉枣
NameList[5].py="fuzongkai";//付宗楷
NameList[6].py="hujingbin";//胡劲斌
NameList[7].py="huangjianwu";//黄建武
NameList[8].py="lailaifa";//赖来发
NameList[9].py="lijiahao";//李嘉豪
NameList[10].py="liangxiaocong";//梁晓聪
NameList[11].py="linchunhua";//林春华
NameList[12].py="liujianhui";//刘建辉
NameList[13].py="luzhijian";//卢志健
NameList[14].py="luonan";//罗楠
NameList[15].py="quegaoxiang";//阙高翔
NameList[16].py="sugan";//苏淦
NameList[17].py="suzhiqiang";//苏志强
NameList[18].py="taojiayang";//陶嘉阳
NameList[19].py="wujiawen";//吴嘉文
NameList[20].py="xiaozhuomin";//肖卓明
NameList[21].py="xujinfeng"; //许金峰
NameList[22].py="yanghaichun";//杨海春
NameList[23].py="yeweixiong";//叶维雄
NameList[24].py="zengwei";//曾玮
NameList[25].py="zhengyongbin";//郑雍斌
NameList[26].py="zhongminghua";//钟明华
NameList[27].py="chenliyan";//陈利燕
NameList[28].py="liuxiaohui";//刘晓慧
NameList[29].py="panjinmei";//潘金梅
for (i=0; i<NAME_NO; i++)
{
s0 = 0;
p = NameList[i].py;
for (j=0; *(p+j)!='\0'; j++)
{
s0 += *(p+j);
}
NameList[i].k = s0;
printf("%13s %d\n", NameList[i].py, NameList[i].k%M );
}
}
(2) 建立哈希表
用除留余数法构建哈希函数,用伪随机探测再散列法处理冲突
void CreateHashList()
{
int i ;
int j;
int collision_cnt = 0;
for (i=0; i<HASH_LENGTH; i++)
{
HashList[i].py = "";
HashList[i].k = 0;
HashList[i].si = 0;
}
for (i=0; i<NAME_NO; i++)
{
int sum = 0;
int adr = (NameList[i].k)%M;
int d = adr;
collision_cnt = 0;
if (HashList[adr].si == 0)
{
printf("\e[48;5;9m success adr %d\e[0m\n", d);
HashList[adr].k = NameList[i].k;
HashList[adr].py = NameList[i].py;
HashList[adr].si=1;
}
else
{
do
{
collision_cnt++;
printf("collision adr=%d\n", d);
d = (d+NameList[i].k%10+1)%M;
sum +=1;
printf("new adr %d, collision_cnt = %d\n",d, collision_cnt);
if (collision_cnt>10)
{
printf("*******fail********\n");
goto out;
}
}while(HashList[d].k != 0);
printf("\e[48;5;9m success adr %d\e[0m\n", d);
HashList[d].k = NameList[i].k;
HashList[d].py = NameList[i].py;
HashList[d].si = sum+1;
}
}
out:
printf("----------------------------------------\n");
j = 0;
for(i=0; i<HASH_LENGTH; i++)
{
if (HashList[i].k != 0)
{
j++;
printf("%d:%13s, %d, %d\n",i, HashList[i].py, HashList[i].k, HashList[i].si );
}
else
{
printf("%d:empty!\n", i);
}
}
printf("-----------totall = %d-------------\n", j);
}
(3) 查找哈希表
void FindList()
{
char name[20] = {0};
int adr;
int d;
int sum=1;
int i;
int s0 = 0;
printf("please input pinyin\n");
scanf("%s", name);
for (i=0; i<20; i++)
{
if(name[i] != '\0')
s0 += name[i];
}
printf("to find: name:%s, key:%d\n", name, s0);
adr = s0%M;
d = adr;
if ((HashList[adr].k == s0) && (strcmp(HashList[adr].py, name) == 0))
printf("find name:%s key=%d, length=1\n", HashList[d].py, s0);
else if (HashList[adr].k == 0)
printf("no record\n");
else
{
do
{
d = (d+s0%10+1)%M;
sum++;
if (HashList[d].k == 0)
{
printf("no record!\n");
break;
}
if ((HashList[d].k == s0) && (strcmp(HashList[d].py, name) == 0))
{
printf("find name:%s, key:%d, search_len=%d\n", HashList[i].py, s0, sum);
break;
}
}while(1);
}
}
4.详细设计
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define NAME_NO 30
#define HASH_LENGTH 50
#define M 50
typedef struct
{
char *py;
int k;
}NAME;
typedef struct
{
char *py;
int k;
int si;
}HASH;
NAME NameList[30];
HASH HashList[HASH_LENGTH];
void init_namelist()
{
int i;
int j;
int s0;
char *p;
NameList[0].py="chenliang";//陈亮
NameList[1].py="chenyuanhao";//陈元浩
NameList[2].py="chengwenliang";//程文亮
NameList[3].py="dinglei";//丁磊
NameList[4].py="fenghanzao";//冯汉枣
NameList[5].py="fuzongkai";//付宗楷
NameList[6].py="hujingbin";//胡劲斌
NameList[7].py="huangjianwu";//黄建武
NameList[8].py="lailaifa";//赖来发
NameList[9].py="lijiahao";//李嘉豪
NameList[10].py="liangxiaocong";//梁晓聪
NameList[11].py="linchunhua";//林春华
NameList[12].py="liujianhui";//刘建辉
NameList[13].py="luzhijian";//卢志健
NameList[14].py="luonan";//罗楠
NameList[15].py="quegaoxiang";//阙高翔
NameList[16].py="sugan";//苏淦
NameList[17].py="suzhiqiang";//苏志强
NameList[18].py="taojiayang";//陶嘉阳
NameList[19].py="wujiawen";//吴嘉文
NameList[20].py="xiaozhuomin";//肖卓明
NameList[21].py="xujinfeng"; //许金峰
NameList[22].py="yanghaichun";//杨海春
NameList[23].py="yeweixiong";//叶维雄
NameList[24].py="zengwei";//曾玮
NameList[25].py="zhengyongbin";//郑雍斌
NameList[26].py="zhongminghua";//钟明华
NameList[27].py="chenliyan";//陈利燕
NameList[28].py="liuxiaohui";//刘晓慧
NameList[29].py="panjinmei";//潘金梅
for (i=0; i<NAME_NO; i++)
{
s0 = 0;
p = NameList[i].py;
for (j=0; *(p+j)!='\0'; j++)
{
s0 += *(p+j);
}
NameList[i].k = s0;
printf("%13s %d\n", NameList[i].py, NameList[i].k%M );
}
}
void CreateHashList()
{
int i ;
int j;
int collision_cnt = 0;
for (i=0; i<HASH_LENGTH; i++)
{
HashList[i].py = "";
HashList[i].k = 0;
HashList[i].si = 0;
}
for (i=0; i<NAME_NO; i++)
{
int sum = 0;
int adr = (NameList[i].k)%M;
int d = adr;
collision_cnt = 0;
if (HashList[adr].si == 0)
{
printf("\e[48;5;9m success adr %d\e[0m\n", d);
HashList[adr].k = NameList[i].k;
HashList[adr].py = NameList[i].py;
HashList[adr].si=1;
}
else
{
do
{
collision_cnt++;
printf("collision adr=%d\n", d);
d = (d+NameList[i].k%10+1)%M;
sum +=1;
printf("new adr %d, collision_cnt = %d\n",d, collision_cnt);
if (collision_cnt>10)
{
printf("*******fail********\n");
goto out;
}
}while(HashList[d].k != 0);
printf("\e[48;5;9m success adr %d\e[0m\n", d);
HashList[d].k = NameList[i].k;
HashList[d].py = NameList[i].py;
HashList[d].si = sum+1;
}
}
out:
printf("----------------------------------------\n");
j = 0;
for(i=0; i<HASH_LENGTH; i++)
{
if (HashList[i].k != 0)
{
j++;
printf("%d:%13s, %d, %d\n",i, HashList[i].py, HashList[i].k, HashList[i].si );
}
else
{
printf("%d:empty!\n", i);
}
}
printf("-----------totall = %d-------------\n", j);
}
void FindList()
{
char name[20] = {0};
int adr;
int d;
int sum=1;
int i;
int s0 = 0;
printf("please input pinyin\n");
scanf("%s", name);
for (i=0; i<20; i++)
{
if(name[i] != '\0')
s0 += name[i];
}
printf("to find: name:%s, key:%d\n", name, s0);
adr = s0%M;
d = adr;
if ((HashList[adr].k == s0) && (strcmp(HashList[adr].py, name) == 0))
printf("find name:%s key=%d, length=1\n", HashList[d].py, s0);
else if (HashList[adr].k == 0)
printf("no record\n");
else
{
do
{
d = (d+s0%10+1)%M;
sum++;
if (HashList[d].k == 0)
{
printf("no record!\n");
break;
}
if ((HashList[d].k == s0) && (strcmp(HashList[d].py, name) == 0))
{
printf("find name:%s, key:%d, search_len=%d\n", HashList[i].py, s0, sum);
break;
}
}while(1);
}
}
int main(void)
{
init_namelist();
CreateHashList();
FindList();
return 0;
}
5.调试分析
在创建时未加入可以从屏幕输入的创建方式,采用的是在程序创建时已将规定好的数据创建。
6.使用说明
1.显示
2.查找
3.退出
选择规定的选项进行相应的操作,对于查找部分是对关键字进行的查找。