散列表的设计与实现.docx
- 文档编号:24128524
- 上传时间:2023-05-24
- 格式:DOCX
- 页数:17
- 大小:158.99KB
散列表的设计与实现.docx
《散列表的设计与实现.docx》由会员分享,可在线阅读,更多相关《散列表的设计与实现.docx(17页珍藏版)》请在冰豆网上搜索。
散列表的设计与实现
中北大学
数据结构
课程设计说明书
学生姓名:
范晓
学号:
1021011537
学院:
软件学院
专业:
软件开发与测试
题目:
散列表的设计与实现
指导教师
何志英
2011年12月20日
1.设计任务概述(包括系统总体框图及功能描述)
总体框图:
功能描述:
1)设每个记录有下列数据项:
电话号码、用户名、地址;
2)从键盘输入各记录,分别以电话号码和用户名为关键字建立散列表;
3)采用一定的方法解决冲突;
4)查找并显示给定电话号码的记录;
5)查找并显示给定用户名的记录。
2.本设计所采用的数据结构(如:
链表、栈、树、图等)
核心数据结构用到的结构体要采用动态内存分配和存放记录的散列表
3.功能模块详细设计
本程序功能模块根据程序设计的需求,综合程序的实用性、人性化、智能化的考虑,将程序划分为几个部分分别编写:
键盘输入各人的信息:
voidgetin()
显示输入的用户信息:
voidShowInformation()
除留余数法构造哈希函数:
intHash1()
构造把字符串转换成整型数哈希函数:
intHash2()
冲突处理函数:
Statuscollision()
以姓名为关键字建表:
voidCreateHash1()
以姓名为关键字查表:
voidSearchHash1()
以电话号码为关键字建表:
voidCreateHash2()
以电话号码为关键字查表:
voidSearchHash2()
输出菜单函数:
intmain()
3.1详细设计思想
要用散列表设计实现电话号码查询系统,对存入的联系人的名字电话以及地址进行存储,并在输入电话号码或姓名后得出此记录的所有信息,要求有菜单界面和清屏功能.首先,此程序,多次用到哈希函数,此处先用除留余数法对折叠后的数构造哈希函数,再用二次探测再散列法建立冲突处理函数解决冲突,再以电话号码和姓名为关键字建立散列表(若哈西地址冲突进行冲突处理),在此之前,必须先用一系列输出函数输出一个菜单.整个程序的设计思路到此结束。
……………………….
3.2核心代码
#include
#include
#include
#include
#defineMAXSIZE20//电话薄记录数量
#defineMAX_SIZE20//人名的最大长度
#defineHASHSIZE53//定义表长
#defineSUCCESS1
#defineUNSUCCESS-1
#defineLENsizeof(HashTable)
typedefintStatus;
typedefcharNA[MAX_SIZE];
typedefstruct{//记录
NAname;
NAtel;
NAadd;
}Record;
typedefstruct{//哈希表
Record*elem[HASHSIZE];//数据元素存储基址
intcount;//当前数据元素个数
intsize;//当前容量
}HashTable;
Statuseq(NAx,NAy){//关键字比较,相等返回SUCCESS;否则返回UNSUCCESS
if(strcmp(x,y)==0)
returnSUCCESS;
elsereturnUNSUCCESS;
}
StatusNUM_BER;//记录的个数
voidgetin(Record*a){//键盘输入各人的信息
printf("输入要添加的个数:
\n");
scanf("%d",&NUM_BER);
inti;
for(i=0;i printf("请输入第%d个记录的用户名: \n",i+1); scanf("%s",a[i].name); printf("请输入%d个记录的电话号码: \n",i+1); scanf("%s",a[i].tel); printf("请输入第%d个记录的地址: \n",i+1); scanf("%s",a[i].add);//gets(str2);? ? ? ? ? ? } } voidShowInformation(Record*a)//显示输入的用户信息 { inti; for(i=0;i printf("\n第%d个用户信息: \n姓名: %s\n电话号码: %s\n联系地址: %s\n",i+1,a[i].name,a[i].tel,a[i].add); } voidCls(Record*a){ printf("*"); system("cls"); } longfold(NAs){//人名的折叠处理 char*p; longsum=0; NAss; strcpy(ss,s);//复制字符串,不改变原字符串的大小写 strupr(ss);//将字符串ss转换为大写形式 p=ss; while(*p! ='\0') sum+=*p++; printf("\nsum====================%d",sum); returnsum; } intHash1(NAstr){//哈希函数 longn; intm; n=fold(str);//先将用户名进行折叠处理 m=n%HASHSIZE;//折叠处理后的数,用除留余数法构造哈希函数 returnm;//并返回模值 } intHash2(NAstr){//哈希函数 longn; intm; n=atoi(str);//把字符串转换成整型数. m=n%HASHSIZE;//用除留余数法构造哈希函数 returnm;//并返回模值 } Statuscollision(intp,int&c){//冲突处理函数,采用二次探测再散列法解决冲突 inti,q; i=c/2+1; while(i if(c%2==0){ c++; q=(p+i*i)%HASHSIZE; if(q>=0)returnq; elsei=c/2+1; } else{ q=(p-i*i)%HASHSIZE; c++; if(q>=0)returnq; elsei=c/2+1; } } returnUNSUCCESS; } voidbenGetTime(); voidCreateHash1(HashTable*H,Record*a){//建表,以人的姓名为关键字,建立相应的散列表 //若哈希地址冲突,进行冲突处理 benGetTime(); inti,p=-1,c,pp; for(i=0;i c=0; p=Hash1(a[i].name); pp=p; while(H->elem[pp]! =NULL){ pp=collision(p,c); if(pp<0){ printf("第%d记录无法解决冲突",i+1);//需要显示冲突次数时输出 continue; }//无法解决冲突,跳入下一循环 } H->elem[pp]=&(a[i]);//求得哈希地址,将信息存入 H->count++; printf("第%d个记录冲突次数为%d。 \n",i+1,c);//需要显示冲突次数时输出 } printf("\n建表完成! \n此哈希表容量为%d,当前表内存储的记录个数为%d.\n",HASHSIZE,H->count); benGetTime(); } voidSearchHash1(HashTable*H,int&c){//在通讯录里查找姓名关键字,若查找成功,显示信息 //c用来记录冲突次数,查找成功时显示冲突次数 benGetTime(); NAstr; printf("\n请输入要查找记录的姓名: \n"); scanf("%s",str); intp,pp; p=Hash1(str); pp=p; while((H->elem[pp]! =NULL)&&(eq(str,H->elem[pp]->name)==-1)) pp=collision(p,c); if(H->elem[pp]! =NULL&&eq(str,H->elem[pp]->name)==1){ printf("\n查找成功! \n查找过程冲突次数为%d.以下是您需要要查找的信息: \n\n",c); printf("姓名: %s\n电话号码: %s\n联系地址: %s\n",H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add); } elseprintf("\n此人不存在,查找不成功! \n"); benGetTime(); } voidbenGetTime(){ SYSTEMTIMEsys; GetLocalTime(&sys); printf("%4d/%02d/%02d%02d: %02d: %02d.%03d\n",sys.wYear,sys.wMonth,sys.wDay,sys.wHour,sys.wMinute,sys.wSecond,sys.wMilliseconds); } voidCreateHash2(HashTable*H,Record*a){//建表,以电话号码为关键字,建立相应的散列表 //若哈希地址冲突,进行冲突处理 benGetTime(); inti,p=-1,c,pp; for(i=0;i c=0; p=Hash2(a[i].tel); pp=p; while(H->elem[pp]! =NULL){ pp=collision(p,c); if(pp<0){ printf("第%d记录无法解决冲突",i+1);//需要显示冲突次数时输出 continue; }//无法解决冲突,跳入下一循环 } H->elem[pp]=&(a[i]);//求得哈希地址,将信息存入 H->count++; printf("第%d个记录冲突次数为%d。 \n",i+1,c);//需要显示冲突次数时输出 } printf("\n建表完成! \n此哈希表容量为%d,当前表内存储的记录个数为%d.\n",HASHSIZE,H->count); benGetTime(); } voidSearchHash2(HashTable*H,int&c){//在通讯录里查找电话号码关键字,若查找成功,显示信息 //c用来记录冲突次数,查找成功时显示冲突次数 benGetTime(); NAtele; printf("\n请输入要查找记录的电话号码: \n"); scanf("%s",tele); intp,pp; p=Hash2(tele); pp=p; while((H->elem[pp]! =NULL)&&(eq(tele,H->elem[pp]->tel)==-1)) pp=collision(p,c); if(H->elem[pp]! =NULL&&eq(tele,H->elem[pp]->tel)==1){ printf("\n查找成功! \n查找过程冲突次数为%d.以下是您需要要查找的信息: \n\n",c); printf("姓名: %s\n电话号码: %s\n联系地址: %s\n",H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add); } elseprintf("\n此人不存在,查找不成功! \n"); benGetTime(); } voidSave(){ FILE*fp; if((fp=fopen("c: \test.txt","w"))==NULL){ printf("\nERRORopeningcustometfile"); } fclose(fp); } intmain(intargc,char*argv[]){ intc,flag=1; HashTable*H; H=(HashTable*)malloc(LEN); for(inti=0;i H->elem[i]=NULL; H->size=HASHSIZE; H->count=0; Recorda[MAXSIZE]; while (1){ printf("\n┏━━━━━━━━━━━━━┓"); printf("\n┃欢迎使用电话号码查找系统┃"); printf("\n┏〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┓"); printf("\n┃★★★★★★★哈希表的设计与实现★★★★★★★┃"); printf("\n┃【1】.添加用户信息┃"); printf("\n┃【2】.读取所有用户信息┃"); printf("\n┃【3】.以姓名建立哈希表(再哈希法解决冲突)┃"); printf("\n┃【4】.以电话号码建立哈希表(再哈希法解决冲突)┃"); printf("\n┃【5】.查找并显示给定用户名的记录┃"); printf("\n┃【6】.查找并显示给定电话号码的记录┃"); printf("\n┃【7】.清屏┃"); printf("\n┃【8】.保存┃"); printf("\n┃【9】.退出程序┃"); printf("\n┃温馨提示: ┃"); printf("\n┃Ⅰ.进行5操作前请先输出3┃"); printf("\n┃Ⅱ.进行6操作前请先输出4┃"); printf("\n┗〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┛"); printf("\n"); printf("请输入一个任务选项>>>"); printf("\n"); intnum; scanf("%d",&num); switch(num){ case1: getin(a); break; case2: ShowInformation(a); break; case3: CreateHash1(H,a);/*以姓名建立哈希表*/ break; case4: CreateHash2(H,a);/*以电话号码建立哈希表*/ break; case5: c=0; SearchHash1(H,c); break; case6: c=0; SearchHash2(H,c); break; case7: Cls(a); break; case8: Save(); break; case9: return0; break; default: printf("你输错了,请重新输入! "); printf("\n"); } } system("pause"); return0; } …………………………… 3.3程序运行结果(拷屏) 程序初始界面如下: 1 2: 输入1添加用户信息,输入2读取 3: 以姓名建立哈希表,再哈希表法解决冲突: 4: 以电话号码建立哈希表,再哈希表法解决冲突 5: 给定用户名查找记录 6: 给定电话号码查找记录 4.课程设计心得、存在问题及解决方法 1)通过这次数据结构的编程题目,使我对数据结构有了更深的了解,熟悉了查找和排序在散列表程序设计中的应用。 2)对查找和排序的时间复杂度和空间复杂度有了进一步了解.从最初的不知道从何入手到最后编写程序的完成,虽然耗费了我们一定的时间跟精力,但同时我们也收获硕果累累,一方面使我对函数的运用有了更加深刻的了解,对面向对象语言更深层次的掌握和应用。 3)在编程过程中,出现了许多的错误,但通过改正,反复思考,对程序的运行方式有了进一步体会,对数据结构设计程序有了进一步体会。 4)我更加懂得,对一个手足无措的程序,不要慌慢慢查阅慢慢体会,心静,努力就有成果.天道酬勤. …………………………
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 列表 设计 实现