1、课程设计散列法 福 建 工 程 学 院课 程 设 计 课程:数据结构课程设计 题目:散列法的实验研究 专业:计算机科学与技术 班级:计 算 机 1001 * * * 学号:3 1 0 0 3 0 1 1 4 2011年12月24日 实验题目:散列法的实验研究第一需要解决的问题首先要输入你的用户信息并构建哈希表,其间会产生冲突我们必须构建一个解决冲突的函数;我们还要以人名和电话号码两种方式建立哈希表。最后,要人名和电话号码方式查找用户信息。在此次设计中需要解决的问题主要有以下几点:1,输入用户信息函数;2,根据输入信息构建哈希表;3,以人名和用户信息的方式搜索用户信息;4,解决输入信息冲突的问题
2、; 第二算法的基本思路描述 输入用户信息时会产生冲突,于是我们构建了二次探测函数来解决冲突,再者应把人名进行折叠处理,然后除留取余数法取得哈希模值,才能用于二次探索。建立好哈希表后,就要以人名和电话号码形式查找信息,就要构造两个函数,最后构建一个主函数起调用作用,将各个函数相互组合串联在一起,形成了具有某种功能的一个小系统。第三算法的设计3.1)数据结构的设计和说明 在设计中运用到了两个结构体,Record结构体中主要包含三项,一个是姓名,电话号码和地址,另一个结构体中有数据元素存储地址,当前数据元素的个数和当前容量。在主函数中首先输出菜单界面,显示菜单界面供使用者选择要操作的序号。当操作者选
3、择出序号后在,switch调用相应的函数。使用者只要根据提示进行操作即可。1-添加用户信息 2-读取所有用户信息 3-以姓名建立哈希表4-以电话号码建立哈希表 5-查找并显示给定用户名的记录 6-查找并显示给定电话号码的记录 7-退出程序 3.2)关键算法设计(其他函数大致相同不详加介绍了)1,冲突处理函数DataType collision(int p,int c) /冲突处理函数,采用二次探测再散列法解决冲突 int i,q; i=c/2+1; /求递增序列 while(i=0) return q; else i=c/2+1; else q=(p-i*i)%HASH_SIZE; c+; i
4、f(q=0) return q; else i=c/2+1; return -1;2,创建哈希表函数void Create_Hash1(HashTable *H,Record *a)/建表,以人名为关键字,建立相应的散列表 若哈希地址冲突,进行冲突处理 int i,p,c=0,pp; for(i=0;ielempp!=NULL) /当表中有值存在时,调用二次探测解决冲突 pp=collision(p,c); if(ppelempp=&(ai);/求得哈希地址,将信息存入 H-count+; printf(n建表完成!n哈希表容量为%d,当前表内存储的记录个数为%dn,HASH_SIZE,H-c
5、ount);3,以人名查找函数void Search_Hash2(HashTable *H,int c) /在通讯录里查找电话号码关键字,若查找成功,显示信息 /c用来记录冲突次数,查找成功时显示冲突次数 elemtype tele; printf(n输入要查找记录的电话号码:); scanf(%s,tele); int p,pp; p=Hash2(tele); /用除留余数法构造哈希函数 pp=p; while(H-elempp!=NULL)&(Equite(tele,H-elempp-telphone)=-1) /当表中地址有值存在时,进行探测处理 pp=collision(p,c); i
6、f(H-elempp!=NULL&Equite(tele,H-elempp-telphone)=1) /当表中的值与要查找的值一样时,成功 printf(n查找成功!以下是您需要查找的信息:n,c); printf(姓名:%s 电话号码:%s 联系地址:%sn,H-elempp-name,H-elempp-telphone,H-elempp-address); else printf(n 此号码不存在,查找失败n); 3.3)模块结构图及各模块功能 算法模块图: 1 主函数int main()主要起调用函数的作用,将其它函数组合起来实现算法功能。2 二次探测函数DataType collisi
7、on(int p, int c)主要是当关键码得到的哈希地址产生冲突时就按照二次探测的方法寻找其他的地址。3 读取函数void Show_Information(Record *s)打印出所有用户的信息。4 创建哈希表void Create_Hash1(HashTable *H, Record *a)以人名构造哈希表。5 创建哈希表void Create_Hash2(HashTable *H, Record *a)以电话号码构造哈希表。6 以姓名方式查找函数void Search_Hash1(HashTable *H, int c)以人名为关键字进行查找。7 以电话号码方式查找函数void S
8、earch_Hash2(HashTable *H, int c)以电话号码为关键字进行查找。8 二次探测函数DataType collision(int p,int c)产生冲突时,以H(key)=(H(key)+d)mod m 方式找到其他空地址,将数据存入。9 折叠函数int fold(elemtype s) 将姓名字符串转化为大写形式计算长度。第四源程序清单 #include#include#include#define MAXSIZE 30 /电话簿记录最大长度#define MAX_SIZE 20 /人名的最大长度#define HASH_SIZE 35 /定义表最大长度#defin
9、e LEN sizeof(HashTable) /结构体HashTable占用的字节数typedef int DataType; /用户自定义typedef char elemtypeMAX_SIZE;typedef struct/记录 elemtype name; elemtype telphone; elemtype address;Record;typedef struct/哈希表 Record *elemHASH_SIZE; /数据元素存储地址 int count; /当前数据元素个数 int size; /当前容量HashTable;DataType num; /记录的个数DataT
10、ype Equite(elemtype x,elemtype y) /关键字比较,相等返回1;否则返回-1 if(strcmp(x,y)=0) return 1; else return -1;void get_Inforamance(Record *s) /输入用户详细信息 printf(请输入要添加的个数:); scanf(%d,&NUM_BER); int i; for(i=0;inum;i+) printf(请输入第%d个记录的用户名:,i+1); scanf(%s,si.name); printf(请输入第%d个记录的电话号码:,i+1); scanf(%s,si.telphone)
11、; printf(请输入第%d个记录的地址:,i+1); scanf(%s,si.address); void Show_Information(Record *s) /输入的用户信息 int i; for(i=0;inum;i+) printf(n第%d个用户信息:姓名:%s 电话号码:%s 联系地址:%s,i+1,si.name,si.telphone,si.address);int fold(elemtype s)/人名的折叠处理 char *p; int sum=0; elemtype a; strcpy(a,s); /复制字符串,不改变原字符串的大小写 strupr(a); /将字符
12、串a转换为大写形式 p=a; while(*p!=0) sum+=*p+; return sum;int Hash1(elemtype str)/哈希函数 int n; int m; n=fold(str);/先将用户名进行折叠处理 m=n%HASH_SIZE; /折叠处理后的数,用除留余数法构造哈希函数 return m; /并返回模值int Hash2(elemtype str) /哈希函数 long n; int m; n=atoi(str); /把字符串转换成整型数 m=n%HASH_SIZE; /用除留余数法构造哈希函数 return m; /并返回余数值DataType colli
13、sion(int p,int c) /冲突处理函数,采用二次探测再散列法解决冲突 int i,q; i=c/2+1; while(i=0) return q; else i=c/2+1; else q=(p-i*i)%HASH_SIZE; c+; if(q=0) return q; else i=c/2+1; return -1;void Create_Hash1(HashTable *H,Record *a)/建表,以人名为关键字,建立相应的散列表 若哈希地址冲突,进行冲突处理 int i,p,c=0,pp; for(i=0;ielempp!=NULL) pp=collision(p,c);
14、 if(ppelempp=&(ai);/求得哈希地址,将信息存入 H-count+; printf(n建表完成!n哈希表容量为%d,当前表内存储的记录个数为%dn,HASH_SIZE,H-count);void Search_Hash1(HashTable *H,int c)/在通讯录里查找姓名关键字,若查找成功,显示信息 c用来记录冲突次数,查找成功时显示冲突次数 elemtype str; printf(n请输入要查找记录的姓名:n); scanf(%s,str); int p,pp; p=Hash1(str); pp=p; while(H-elempp!=NULL)&(Equite(st
15、r,H-elempp-name)=-1) pp=collision(p,c); if(H-elempp!=NULL&Equite(str,H-elempp-name)=1) printf(n查找成功!以下是您需要查找的信息:n,c); printf(姓名:%s电话号码:%s联系地址:%sn,H-elempp-name,H-elempp-telphone,H-elempp-address); else printf(n此人不存在,查找失败n);void Create_Hash2(HashTable *H,Record *a) /建表,以电话号码为关键字,建立相应的散列表 /若哈希地址冲突,进行冲
16、突处理 int i,p=-1,c=0,pp; for(i=0;ielempp!=NULL) pp=collision(p,c); if(ppelempp=&(ai);/求得哈希地址,将信息存入 H-count+; printf(n建表完成!n哈希表容量为%d,当前表内存储的记录个数为%dn,HASH_SIZE,H-count);void Search_Hash2(HashTable *H,int c) /在通讯录里查找电话号码关键字,若查找成功,显示信息 /c用来记录冲突次数,查找成功时显示冲突次数 elemtype tele; printf(n输入要查找记录的电话号码:); scanf(%s
17、,tele); int p,pp; p=Hash2(tele); pp=p; while(H-elempp!=NULL)&(Equite(tele,H-elempp-telphone)=-1) pp=collision(p,c); if(H-elempp!=NULL&Equite(tele,H-elempp-telphone)=1) printf(n查找成功!以下是您需要查找的信息:n,c); printf(姓名:%s 电话号码:%s 联系地址:%sn,H-elempp-name,H-elempp-telphone,H-elempp-address); else printf(n 此号码不存在
18、,查找失败n); int main(int arge,char *argv) printf( 计算机1001 学号:3100301114 张扬文 n); int c,i,flag=1; HashTable *H; H=(HashTable *)malloc(LEN); for(i=0;ielemi=NULL; H-size=HASH_SIZE; H-count=0; Record aMAXSIZE; while(1)printf(n ); printf(n *欢迎使用电话号码查找系统*); printf(n =);printf(n*哈希表的设计与实现*); printf(n | 1-添加用户信
19、息 |); printf(n | 2-读取所有用户信息 |); printf(n | 3-以姓名建立哈希表 |); printf(n | 4-以电话号码建立哈希表 |); printf(n | 5-查找并显示给定用户名的记录 |); printf(n | 6-查找并显示给定电话号码的记录 |); printf(n | 0-退出程序 |); printf(n ); printf(n 进行操作时先输入1-添加用户信息,请输入你的操作:); int num; scanf(%d,&num); switch(num) case 1: get_Inforamance(a); break; case 2:
20、Show_Information(a); break; case 3: Create_Hash1(H,a); /*以姓名建立哈希表*/ break; case 4: Create_Hash2(H,a); /*以电话号码建立哈希表*/ break; case 5: c=0; Search_Hash1(H,c); break; case 6: c=0; Search_Hash2(H,c); break; case 0: return 0; break; default: printf(输入错误,请重新输入!!); printf(n); return 0;第五测试数据及测试结果 菜单界面:添加用户:
21、读取用户信息:以姓名方式建立哈希表:以电话号码方式建立哈希表:以姓名方式查找:以电话号码方式查找:第六课程设计总结及心得体会通过这次课程设计,使我对哈希表和哈希函数的相关知识有了较多的了解,并且掌握了用二次探测构建哈希表的方法,充满了收获,获得了一些以前没学到的知识,对程序的运行方式有了一定的体会。 这次设计给我最深的就是,一定要把课本上的知识吃透,因为这是做实验的基础,否则,在老师讲解时久听不懂,这会使实验难度加大,浪费做实验的宝贵时间。做实验一定要亲力亲为,务必要将每个细节,每个步骤弄清楚,弄明白,还要复习,思考。这样,你的印象才深刻,才记得牢固,否则,过后就忘了还不如不做,就好像没有积累
22、好的素材写不出好的文章。 每次的实验都让我受益非浅,这次课程设计更使我有了更大的收获。明白了字符串的很多操作算法的编写和理解,并且查阅了大量的资料,对哈希表的相关知识有了很大的了解。期间遇到了很多的问题,其实我觉得编写程序,调试,遇到问题耐心的查错,总会有解决办法的,比较困难的错误其实是能够运行之后结果不稳定,有时候对,有时候错,这样的问题往往是程序设计的算法的问题,虽然这次程序没有太复杂的算法,但是一些小的地方没有考虑到,往往会给运行结果造成很多难以解释的错误。我觉得我的程序在经过很多种情况的测试后,基本上能满足我自己的要求了,可能还有很多不完善的地方,但是确实收获了很多东西,随着以后的学习运用,估计会有更深入的认识。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1