哈希表.docx
- 文档编号:30543368
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:19
- 大小:234.35KB
哈希表.docx
《哈希表.docx》由会员分享,可在线阅读,更多相关《哈希表.docx(19页珍藏版)》请在冰豆网上搜索。
哈希表
哈希表设计
班级:
姓名:
学号:
一、问题描述
1.问题描述
针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得查找长度均不超过R,完成相应的建表和查表顺序。
2.基本要求
假设人名为中国人姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构造,用伪随机探测再散列法处理冲突。
二、需求分析
(1)针对某个集体中的人名设计一个哈希表,使得平均查找长度不超过R,完成相应的建立和查表程序。
(2)人名为汉语拼音形式,最长不超过19个字符(如:
庄双双zhuangshuangshuang)。
(3)假设待填入哈希表的人名有30个,平均查找长度的上限为2。
哈希表用除留余数法构造,用伪随机探测在散列法处理冲突。
(4)查找成功时,显示姓名及关键字,并计算和输出查找成功的平均查找长度。
三、概要设计
1.构造结构体:
typedefstruct{};
2.姓名表的初始化:
voidInitNameTable();
3.建立哈希表:
voidCreateHashTable();
4.显示姓名表:
voidDisplayNameTable();
5.姓名查找:
voidFindName();
6.主函数:
voidmain() ;
各个部分的关系如下:
四、详细设计
1.存储结构设计
typedefstruct
{char*py;//名字的拼音
intk;//拼音所对应的整数
}NAME;
typedefstruct//哈希表
{char*py;//名字的拼音
intk;//拼音所对应的整数
intsi;//查找长度
}HASH;
2.姓名表的初始化
voidInitNameTable()//姓名表的初始化
{
NameTable[0].py="chengnuo";
NameTable[1].py="cuihongwei";
NameTable[2].py="cuijia";
NameTable[3].py="cuirongchao";
NameTable[4].py="dingsheng";
NameTable[5].py="guqi";
NameTable[6].py="hanyanyan";
NameTable[7].py="zhengyawen";
NameTable[8].py="jiaxiyang";
NameTable[9].py="jiangxiaobin";
NameTable[10].py="jiangxiaohui";
NameTable[11].py="lidandan";
NameTable[12].py="lilin";
NameTable[13].py="lishanshan";
NameTable[14].py="liuxiaowen";
NameTable[15].py="liuxinhao";
NameTable[16].py="luxiaolin";
NameTable[17].py="luyingying";
NameTable[18].py="shaojiakun";
NameTable[19].py="songjiajin";
NameTable[20].py="sunhui";
NameTable[21].py="wanchengcheng";
NameTable[22].py="wanbo";
NameTable[23].py="wanghongyang";
NameTable[24].py="yuyang";
NameTable[25].py="yujunde";
NameTable[26].py="xulong";
NameTable[27].py="zhangxinghua";
NameTable[28].py="zhaolongxiang";
NameTable[29].py="zhengna";
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; } } 3.建立哈希表 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; } } } 4.显示姓名表与哈希表 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); } 5.姓名查找 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; } } } 6.主函数 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; } 五、调试分析 本程序的思路较简单,主要是对哈希表的建立,查找和输出,在写程序时最重要的是正确书写哈希函数和用伪随机探测再散列法处理冲突,真确处理可以有效减少查找长度,提高程序运行效率。 2、通过此程序的编写,慢慢了解了哈希表原理和功用3、查找过程中曾遇到输入不同的名字。 会显示相同的结果,说明哈希函数还有待改进。 六、测试结果 源代码 #include #include #include #include #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="chengnuo"; NameTable[1].py="cuihongwei"; NameTable[2].py="cuijia"; NameTable[3].py="cuirongchao"; NameTable[4].py="dingsheng"; NameTable[5].py="guqi"; NameTable[6].py="hanyanyan"; NameTable[7].py="zhengyawen"; NameTable[8].py="jiaxiyang"; NameTable[9].py="jiangxiaobin"; NameTable[10].py="jiangxiaohui"; NameTable[11].py="lidandan"; NameTable[12].py="lilin"; NameTable[13].py="lishanshan"; NameTable[14].py="liuxiaowen"; NameTable[15].py="liuxinhao"; NameTable[16].py="luxiaolin"; NameTable[17].py="luyingying"; NameTable[18].py="shaojiakun"; NameTable[19].py="songjiajin"; NameTable[20].py="sunhui"; NameTable[21].py="wanchengcheng"; NameTable[22].py="wanbo"; NameTable[23].py="wanghongyang"; NameTable[24].py="yuyang"; NameTable[25].py="yujunde"; NameTable[26].py="xulong"; NameTable[27].py="zhangxinghua"; NameTable[28].py="zhaolongxiang"; NameTable[29].py="zhengna"; 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;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); } 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; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈希表