大数据结构哈希表设计.docx
《大数据结构哈希表设计.docx》由会员分享,可在线阅读,更多相关《大数据结构哈希表设计.docx(13页珍藏版)》请在冰豆网上搜索。
大数据结构哈希表设计
实验六:
存储管理、查找和排序
题目:
哈希表设计
班级:
姓名:
学号:
一、问题描述
针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度均不超过R,完成相应的建表和查表顺序。
二、基本要求
假设人名为中国人姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构造,用伪随机探测再散列法处理冲突。
三、概要设计
1.构造结构体:
typedefstruct{};
2.姓名表的初始化:
voidInitNameTable();
3.建立哈希表:
voidCreateHashTable();
4.显示姓名表:
voidDisplayNameTable();
5.姓名查找:
voidFindName();
6.主函数:
voidmain() ;
四、详细设计
1.姓名表的初始化
voidInitNameTable()
{
NameTable[0].py="louyuhong";
NameTable[1].py="shenyinghong";
NameTable[2].py="wangqi";
NameTable[3].py="zhuxiaotong";
NameTable[4].py="zhataotao";
NameTable[5].py="chenbinjie";
NameTable[6].py="chenchaoqun";
NameTable[7].py="chencheng";
NameTable[8].py="chenjie";
NameTable[9].py="chenweida";
NameTable[10].py="shanjianfeng";
NameTable[11].py="fangyixin";
NameTable[12].py="houfeng";
NameTable[13].py="hujiaming";
NameTable[14].py="huangjiaju";
NameTable[15].py="huanqingsong";
NameTable[16].py="jianghe";
NameTable[17].py="jinleicheng";
NameTable[18].py="libiao";
NameTable[19].py="liqi";
NameTable[20].py="lirenhua";
NameTable[21].py="liukai";
NameTable[22].py="louhanglin";
NameTable[23].py="luchaoming";
NameTable[24].py="luqiuwei";
NameTable[25].py="panhaijian";
NameTable[26].py="shuxiang";
NameTable[27].py="suxiaolei";
NameTable[28].py="sunyubo";
NameTable[29].py="wangwei";
for(i=0;i {
ints=0;
char*p=NameTable[i].py;
for(j=0;*(p+j)!
='\0';j++)
s+=toascii(*(p+j));
NameTable[i].m=s;
}
}
2.建立哈希表
voidCreateHashTable()
{
for(i=0;i {
HashTable[i].py="\0";
HashTable[i].m=0;
HashTable[i].si=0;
}
for(i=0;i {
intsum=1,j=0;
intadr=(NameTable[i].m)%P; //除留余数法H(key)=keyMODp,p<=m
if(HashTable[adr].si==0) //如果不冲突,将姓名表赋值给哈希表
{
HashTable[adr].m=NameTable[i].m;
HashTable[adr].py=NameTable[i].py;
HashTable[adr].si=1;
}
else //如果冲突
{
while(HashTable[adr].si!
=0)
{
adr=(adr+d[j++])%HASH_LEN; //伪随机探测再散列法处理冲突
sum=sum+1; //查找次数加1
}
HashTable[adr].m=NameTable[i].m; //将姓名表复制给哈希表对应的位置上
HashTable[adr].py=NameTable[i].py;
HashTable[adr].si=sum;
}
}
}
3.显示姓名表与哈希表
voidDisplayNameTable()
{
printf("\n地址\t\t姓名\t\t关键字\n");
for(i=0;i printf("%2d%18s\t\t %d \n",i,NameTable[i].py,NameTable[i].m);
}
voidDisplayHashTable()
{
floatasl=0.0;
printf("\n\n地址\t\t姓名\t\t关键字\t搜索长度\n");//显示的格式
for(i=0;i {
printf("%2d%18s\t\t %d\t\t %d\n",i,HashTable[i].py,HashTable[i].m,HashTable[i].si);
asl+=HashTable[i].si;
}
asl/=NAME_LEN; //求得ASL
printf("\n\n平均查找长度:
ASL(%d)=%f\n",NAME_LEN,asl);
}
4.姓名查找
voidFindName()
{
charname[20]={0};
ints=0,sum=1,adr;
printf("\n请输入想要查找的姓名的拼音:
");
scanf("%s",name);
for(j=0;j<20;j++) //求出姓名的拼音所对应的ASCII作为关键字
s+=toascii(name[j]);
adr=s%P; //除留余数法
j=0;
if(HashTable[adr].m==s&&!
strcmp(HashTable[adr].py,name)) //分3种情况进行判断,并输出超找结果
printf("\n姓名:
%s 关键字:
%d 查找长度为:
1\n",HashTable[adr].py,s);
elseif(HashTable[adr].m==0)
printf("没有想要查找的人!
\n");
else
{
while
(1)
{
adr=(adr+d[j++])%HASH_LEN; //伪随机探测再散列法处理冲突
sum=sum+1; //查找次数加1
if(HashTable[adr].m==0)
{
printf("没有想要查找的人!
\n");
break;
}
if(HashTable[adr].m==s&&!
strcmp(HashTable[adr].py,name))
{
printf("\n姓名:
%s 关键字:
%d 查找长度为:
%d\n",HashTable[adr].py,s,sum);
break;
}
}
}
}
五、测试结果
六、实验环境
C-Free
七、源程序代码
#include
#include//time用到的头文件
#include//随机数用到的头文件
#include//toascii()用到的头文件
#include//查找姓名时比较用的头文件
#defineHASH_LEN50//哈希表的长度
#defineP47//小于哈希表长度的P
#defineNAME_LEN30//姓名表的长度
typedefstruct//姓名表
{
char*py;//名字的拼音
intm;//拼音所对应的
}NAME;
NAMENameTable[HASH_LEN];//全局定义姓名表
typedefstruct//哈希表
{
char*py;//名字的拼音
intm;//拼音所对应的ASCII总和
intsi;//查找长度
}HASH;
HASHHashTable[HASH_LEN];//全局定义哈希表
intd[30],i,j;//全局定义随机数,循环用的i、j
voidInitNameTable()//姓名表的初始化
{
NameTable[0].py="louyuhong";
NameTable[1].py="shenyinghong";
NameTable[2].py="wangqi";
NameTable[3].py="zhuxiaotong";
NameTable[4].py="zhataotao";
NameTable[5].py="chenbinjie";
NameTable[6].py="chenchaoqun";
NameTable[7].py="chencheng";
NameTable[8].py="chenjie";
NameTable[9].py="chenweida";
NameTable[10].py="shanjianfeng";
NameTable[11].py="fangyixin";
NameTable[12].py="houfeng";
NameTable[13].py="hujiaming";
NameTable[14].py="huangjiaju";
NameTable[15].py="huanqingsong";
NameTable[16].py="jianghe";
NameTable[17].py="jinleicheng";
NameTable[18].py="libiao";
NameTable[19].py="liqi";
NameTable[20].py="lirenhua";
NameTable[21].py="liukai";
NameTable[22].py="louhanglin";
NameTable[23].py="luchaoming";
NameTable[24].py="luqiuwei";
NameTable[25].py="panhaijian";
NameTable[26].py="shuxiang";
NameTable[27].py="suxiaolei";
NameTable[28].py="sunyubo";
NameTable[29].py="wangwei";
for(i=0;i{
ints=0;
char*p=NameTable[i].py;
for(j=0;*(p+j)!
='\0';j++)
s+=toascii(*(p+j));
NameTable[i].m=s;
}
}
voidCreateHashTable()//建立哈希表
{
for(i=0;i{
HashTable[i].py="\0";
HashTable[i].m=0;
HashTable[i].si=0;
}
for(i=0;i{
intsum=1,j=0;
intadr=(NameTable[i].m)%P;//除留余数法H(key)=keyMODp,p<=m
if(HashTable[adr].si==0)//如果不冲突,将姓名表赋值给哈希表
{
HashTable[adr].m=NameTable[i].m;
HashTable[adr].py=NameTable[i].py;
HashTable[adr].si=1;
}
else//如果冲突
{
while(HashTable[adr].si!
=0)
{
adr=(adr+d[j++])%HASH_LEN;//伪随机探测再散列法处理冲突
sum=sum+1;//查找次数加1
}
HashTable[adr].m=NameTable[i].m;//将姓名表复制给哈希表对应的位置上
HashTable[adr].py=NameTable[i].py;
HashTable[adr].si=sum;
}
}
}
voidDisplayNameTable()//显示姓名表
{
printf("\n地址\t\t姓名\t\t关键字\n");
for(i=0;iprintf("%2d%18s\t\t%d\n",i,NameTable[i].py,NameTable[i].m);
}
voidDisplayHashTable()//显示哈希表
{
floatasl=0.0;
printf("\n\n地址\t\t姓名\t\t关键字\t搜索长度\n");//显示的格式
for(i=0;i{
printf("%2d%18s\t\t%d\t\t%d\n",i,HashTable[i].py,HashTable[i].m,HashTable[i].si);
asl+=HashTable[i].si;
}
asl/=NAME_LEN;//求得ASL
printf("\n\n平均查找长度:
ASL(%d)=%f\n",NAME_LEN,asl);
}
voidFindName()//查找
{
charname[20]={0};
ints=0,sum=1,adr;
printf("\n请输入想要查找的姓名的拼音:
");
scanf("%s",name);
for(j=0;j<20;j++)//求出姓名的拼音所对应的ASCII作为关键字
s+=toascii(name[j]);
adr=s%P;//除留余数法
j=0;
if(HashTable[adr].m==s&&!
strcmp(HashTable[adr].py,name))//分3种情况进行判断,并输出超找结果
printf("\n姓名:
%s关键字:
%d查找长度为:
1\n",HashTable[adr].py,s);
elseif(HashTable[adr].m==0)
printf("没有想要查找的人!
\n");
else
{
while
(1)
{
adr=(adr+d[j++])%HASH_LEN;//伪随机探测再散列法处理冲突
sum=sum+1;//查找次数加1
if(HashTable[adr].m==0)
{
printf("没有想要查找的人!
\n");
break;
}
if(HashTable[adr].m==s&&!
strcmp(HashTable[adr].py,name))
{
printf("\n姓名:
%s关键字:
%d查找长度为:
%d\n",HashTable[adr].py,s,sum);
break;
}
}
}
}
intmain()//主函数
{
chara;
srand((int)time(0));
for(i=0;i<30;i++)//用随机函数求得伪随机数列d[i](在1到50之间)
d[i]=1+(int)(HASH_LEN*rand()/(RAND_MAX+1.0));
InitNameTable();
CreateHashTable();
puts("哈希表设计");//显示菜单栏
start:
puts("\n*----------------------------菜单栏------------------------------*");puts("\t\t\t1.显示姓名表");
puts("\t\t\t2.显示哈希表");
puts("\t\t\t3.查找");
puts("\t\t\t4.退出");
puts("*----------------------------------------------------------------*");
restart:
printf("\n\t请选择:
");
scanf("%s",&a);
switch(a)//根据选择进行判断,直到选择退出时才可以退出
{
case'1':
DisplayNameTable();
break;
case'2':
DisplayHashTable();
break;
case'3':
FindName();
break;
case'4':
exit(0);
break;
default:
printf("\n请输入正确的选择!
\n");
gotorestart;
}
gotostart;
}