用散列表建立通讯录.docx
《用散列表建立通讯录.docx》由会员分享,可在线阅读,更多相关《用散列表建立通讯录.docx(24页珍藏版)》请在冰豆网上搜索。
![用散列表建立通讯录.docx](https://file1.bdocx.com/fileroot1/2023-1/9/956186c7-ab2b-4962-9549-8f0fcb78594f/956186c7-ab2b-4962-9549-8f0fcb78594f1.gif)
用散列表建立通讯录
学院
课程设计报告
课程名称:
数据结构与算法
设计题目:
用散列表建立通讯录
系另计算机科学与技术
专业:
计算机科学与技术
组别:
第六组
起止日期:
2011年5月20日~2011年6月20日
指导教师:
斌
计算机科学与技术系二。
一一年制
课程设计任务书
课程设计题目
建立通讯录
组长
光
学号
2010211133班级10计科1班
系别
计算机科学与技术
专业
10计算机科学与技术
组员
王春、宗辉、擎昱、光
指导教师
斌
课程设计目的
(1)熟练掌握C语言的基本知识和技能;
(2)基本掌握面向对象程序设计的基本思路和方法;
(3)能够利用所学的基本知识和技能,解决简单的程序设计问题。
课程设计所需环境
MicrosoftVisualC++6.0
课程设计任务要求
(1)设每个记录有下列数据项:
、用户名、地址;
(2)从键盘输入各记录,分别以为关键字建立散列表;
(3)米用二次探测再散列法解决冲突;
(4)查找并显示给定的记录;
(5)通讯录信息文件保存;
(6)要求人机界面友好,使用图形化界面;
课程设计工作进度计划
序号
起止日期
工作容
分工情况
1
2011.5.22—2011.5.30
概要设计
王春、宗辉
2
201161—2011.6.10
详细代码
擎昱一显示语言选单、创建、在通讯录的结尾写入信息;王春一查询与修改;宗辉一删除与显示;光一退出、文件的操作
3
2011.6.4—2011.6.8
需求分析
擎昱
4
2011.6.8—2011.6.12
调试与操作说明
全体成员
5
2011.6.12—2011.6.14
总结与体会
全体成员
6
2011.6.15—2011.6.18
引言
光
教研室审核意见:
教研室主任签字:
年月日
一、引言1
二、需求分析1
⑴课程设计题目1
(2)课程设计的目的1
(3)课程设计的要求1
(4)课程设计的主要思想2
三、概要设计2
(1)流程图2
(2)设计方法及原理7
四、详细容7
五、调试与操作说明17
(1)主界面17
(2)创建17
(3)修改18
(4)删除18
(5)显示19
(6)从文件读取19
六、课程设计总结与体会20
七、致谢20
八、参考文献20
目录格式在做修改,请按照第三组的格式或者模板的格式认证修改!
、引言
“课程设计”是大学里考查在校学生对本专业所学的知识掌握情况的一种方法,也是对
学生对团队合作精神的一种考验。
本课程设计的要用散列表建立通讯录。
其中,散列表主要
是运用《数据结构》中的除留余数发,而处理冲突是运用二次探测法⑴。
在通信录的存储中,
主要是先用一个数组将其存储,这主要是为了在建立哈希表的时候便于操作。
建立哈希表时,
用的是将字符型数字转化为整形数据,用的是atoi()函数,在stdlib.h
(2)头文件里。
由于这次
的课程设计,在通信录中要操作的功能有很多,所以在主函数里用了switch()函数,通过case
的选值不同执行不同的操作。
由于在现示主界面的时候,要运用Esc键返回主界面,所以用
了getch()函数来得到Esc键,而getch()函数实在conio.h⑶头文件里。
在本次设计中,因为在删除与查找的过程中,要比较输入的字符串与保存的字符串是否相等,用到了strcmp()函
数,它是包含在string.h⑷头文件里。
课程设计中,为了使界面效果更好一些,我们使用了清屏函数system(“cls”),它包含在stdlib.h(5)头文件里和得至U系统时间的函数,包含在
windows.h头文件里。
在本次的课程设计中,我们小组的各位同学都全部投入,由于我们是第一次做课程设计,所以在其中含有一些问题,望各位老师批评指正。
参考文献标注要用[]号,不要用()
、需求分析
(1)课程设计题目
这一组的课程设计题目是《用哈希表建立通讯录》,并实现语言选单、创建、修改、查
询、删除、文件的操作等。
(2)课程设计的目的
掌握数据结构的基础技术,学会分析研究计算机加工的数据结构的特性,以便应用涉及的数据选择适当的逻辑结构、存储结构及其相应的算法,应用相关知设计设散列表实现查找系统。
(3)课程设计的要求
【基本要求】
①设每个记录有下列数据项:
、用户名、地址;
㈢从键盘输入各记录,分别以为关键字建立散列表;
③采用二次探测再散列法解决冲突;
⑷查找并显示给定的记录;
③通讯录信息文件保存;
@要求人机界面友好,使用图形化界面;
【选做容】
3系统功能的完善;
㈢设计不同的散列函数,比较冲突率;
3在散列函数确定的前提下,尝试各种不同类型处理冲突的方法,考察平均查找长度的变化。
3使用汉字显示。
(4)课程设计的主要思想
课程设计中,通过不同的选择输入,实现不同的功能。
有语言提示,它是通过不同的输入选
择不同的语言。
在通信录的创建中,把输入的信息保存在一个数组里,通过输入的,将其转
化为数据,通过取余,找到它在哈希表的位置,如果位置冲突,就用二次探测处理。
在查找中,通过输入的,调用哈希表寻找它在哈希表的位置,并把它输出。
同样,修改于删除都是通过同样的的道理找到它在哈希表中的位置。
在修改的时候,通过不同的修改选单实现不同
的修改,在删除的时候,找到它的位置,在输出的的时候不输出,其实它并没有真正意义的被删除。
三、概要设计
(1)流程图
3概括图
②创建
建立的号码
tel
字符转为数据
结束
0查找
「开始一
要找的号码tel
字符转为数据
PP=
HASH(tel)
为空,
且相等
pp=collision(p,c)
Y
找到V
[结束
◎修改
输入号
码tel
字符转化为数据
图4修改的流程图
©删除
f开始.
输入号
码tel
字符转化为数据
图5删除的流程图
(2)设计方法及原理
主函数里,对不同的子函数,通过的到的不同字符对其进行调用。
在建立通讯录中,用了哈
希表的建立,在哈希表中,是将字符型数字转化为整形数据,并对哈希表的原有长度取余得
到存储的位置,而得到的位置可能已被使用,故有调用了二次哈希,并以最后处理的下标是否为非负,来决定是存储还是不存储。
,而在下面的查询、删除、修改中,都是调用哈希表,找到它在哈希表中的位置来进行不同的操作。
其中,在删除时,用了一个全局变量来存储要
删除的位置的下标,在输出的时候不将其输出,而真正意义上,它并没有从保存的位置删除。
在修改中,通过选择不同。
来修改不同的信息。
这个设计,主要就是对哈希表的调用与冲突的处理。
四、详细容
程序代码
#include
#include
#include
#inelude
#include
#defineMAXSIZE200
#defineMAX_SIZE20
#defineHASHSIZE67
II为了使用getch()方法
//薄记录数量
〃人名的最大长度
II定义表长
#defineLENsizeof(HashTable)typedefintStatus;
typedefcharFRI[MAX_SIZE];
intss=201;II用于帮助删除
typedefstruct{II记录
FRIname;
FRItel;
FRIadd;
}Record;
typedefstruct{II哈希表
Record*elem[HASHSIZE];〃数据元素存储基址
intcount;II当前数据元素个数
intsize;II最大容量
}HashTable;
voidSystemTime()II显示系统时间
SYSTEMTIMEsys;
GetLocalTime(&sys);
printf("%4d/%02d/%02d\n%02d:
%02d:
%02d.%03d",sys.wYear,sys.wMonth,sys.wDay,sys.w
Hour,sys.wMinute,sys.wSecond,sys.wMilliseconds);
}
voidPR1()
{
SystemTime();
printf("\t\t\t通讯录操作的目录\n\n");
voidPR11()
printf("\t\t\tDirectoriesoperationdirectory\n\n");
}
voidPR2()
{
printf("\t按a键,显示语言提示选单\t\t");
printf("按b键,创建新的通讯录\n\n”);
printf("\t按c键,在通信录的末尾写入新的信息\t\t");
printf("按d键,查询某人的信息\n\n”);
printf("\t按e键,修改某人的信息\t\t");
printf("按f键,删除某人的信息\n\n");
printf("\t按g键,显示通讯录中的所有记录\t\t");
printf("按h键,退出选单\n\n”);
printf("\t按i键,保存通讯录中的所有记录到指定文件中\n\n");
printf("\t按j键,从指定文件中读取通讯录中的记录\n");
printf("\n友情提示:
\n\t先建立方可进行查找、修改、删除、显示,在从文件读取前,应先
存入文件\n\n”);
printf("\t");
}
voidPR22()
{
printf("\tPressingakey,Languagemenu\n\n");
printf("\tPressingbkey,Createanewaddressbook\n\n”);
printf("\tPressingckey,Theendofthecommunicationrecordtowriteanew
\n\tinformation\n\in");
Inquirestheinformation.Someone\n\n");
Modifysomeone'sinformation\n\n");
Removesomeone'sinformation\n\n");
Alltherecordsshowdirectories\n\n");
printf("\tPressinghkey,Exitmenu\n\n");
printf("\tPressingikey,Savealltherecordstothespecifieddirectoryfile\n\n");
printf("\tPressingjkey,Readdirectoriesfromaspecifiedfilerecordin\n\n");
printf("\nHelpfulhints:
\n\tTocreatecansearch,modify,delete,display,inreadfromthefile,");
printf("\n'tshouldfirstbeforedepositfiles'n\n");
printf("\t");
voidPR3()
printf("\n\t\t*
**********************
*\n");
SystemTime();
printf("\t\t\t创建通讯录\n\n”);
voidPR4(inti)
SystemTime();
printf("\t\t\t查询某人的信息\n\n");
voidPR5()
SystemTime();
printf("\t\t\t修改某人的信息\n\n");
voidPR6()
SystemTime();
printf("\t\t\t\t删除某人的信息\n\n");
voidPR7()
SystemTime();
printf("\t\t\t在通信录的末尾写入新的信息\n\n");
voidPR8()
SystemTime();
printf("\t\t\t通讯录中已存信息\n\n");
voidPR9()
SystemTime();
printf("\t\t\t从文件中读取结果\n\n");
voidMenu()
{
system("cls");
选择语言:
");
intn;
printf("\n\n\n\n\n\n\n\n\n\t\t\t输入1(汉语)、2(英语)scanf("%d",&n);
system("cls");
if(n==1)
{
PR1();
PR2();
}
if(n==2)
{
PR11();
PR22();
}
}
intNUM_BER=0;
intcollision(intp,int&c){
inta,pp;
a=c/2+1;
while(a{
if(a%2==0)
{
c++;
pp=(p+2*a)%HASHSIZE;if(pp>0)
returnpp;
else
a=c/2+1;
}
else
{
pp=(p-2*a)%HASHSIZE;
C++;
if(PP>0)
returnpp;
else
a=c/2+1;
}
}
return-1;
}
intHASH(FRIte)//哈希函数
{
intm;
longn;
n=atoi(te);
m=n%HASHSIZE;
returnm;
}
voidAppend()//写入后继容
{
system("cls");
FILE*fp;
FRIpa;
PR7();
if((fp=fopen("D:
\\wo.txt","ab+"))==NULL)
printf("\tFileopenerroe!
");
printf("\n\t输入追加的容:
”);
gets(pa);
fwrite(pa,sizeof(FRI),1,fp);
fclose(fp);
printf("\n\n\n\t\t按Esc键,返回主菜单”);
}
voidCreateHash(HashTable*H,Record*a)//以为关键字
{
//SystemTime();
inti,c,p=-1,pp;
for(i=0;i{
c=0;
p=HASH(a[i].tel);
pp=p;
while(H->elem[pp]!
=NULL)
{
pp=collision(p,c);
if(PP<0)
{
printf("\t第%d记录无法解决冲突",i+1);
continue;
}
}
H->elem[pp]=&(a[i]);
H->count++;
}
printf("\n\t\t\t建表完成!
\n\n\t\t散列表的容量为%d,当前容量为%d
”,HASHSIZE,H->count);
}
voidgetin(Record*a,HashTable*H)//键盘输入个人的信息
{
system("cls");
PR3();
printf("\t输入要添加的个数:
”);
scanf("%d",&NUM_BER);
inti;
for(i=0;i{
printf("\n\t\t\t\t请输入第%d个的记录\n”,i+1);
printf("\t输入其:
");
fflush(stdin);
gets(a[i].name);
printf("\n\t输入其:
");
fflush(stdin);
gets(a[i].tel);
printf("\n\t输入其地址:
”);
fflush(stdin);
gets(a[i].add);
}
CreateHash(H,a);〃建立散列表存储
printf("\n\n\t按Esc键,返回主菜单”);
}
intbj(FRItel1,FRItel2)//字符串的比较
{
if(strcmp(tel1,tel2)==0)
return1;
else
return0;
}
voidFind(HashTable*H,int&c)〃查找
{
system("cls");
PR4(0);
fflush(stdin);
FRItel;
intp,pp;
printf("\n\t输入要查找的:
”);
gets(tel);
p=HASH(tel);
PP=P;
while(H->elem[pp]!
=NULL&&bj(tel,H->elem[pp]->tel)==0)
pp=collision(p,c);
if(H->elem[pp]!
=NULL&&bj(tel,H->elem[pp]->tel)==1)
{
printf("\n\t\t\t查找成功\n\n");
printf("\t:
%s\n\n\t:
%s\n\n\t联系地
址:
%s\n“,H_>elem[pp]_>name,H->elem[pp]->tel,H->elem[pp]->add);
}
else
printf("\n\t此人不存在,失败!
\n");
printf("\n\t按Esc键,返回主菜单");
}
voidAlter(HashTable*H,int&c)//修改
{
system("cls");
PR5();
fflush(stdin);
FRItel;
FRIgai;
intp,pp,i;
printf("\n\t输入要修改信息的:
”);
gets(tel);
p=HASH(tel);
pp=p;
while(H->elem[pp]!
=NULL&&bj(tel,H->elem[pp]->tel)==0)
pp=collision(p,c);
if(H->elem[pp]!
=NULL&&bj(tel,H->elem[pp]->tel)==1)
{
printf("\n\t输入1,2来选择修改项【1:
修改,2:
修改地址】:
”);
scanf("%d",&i);
switch(i)
{
case1:
fflush(stdin);
printf("\n\t输入要修改后的:
”);
gets(gai);
strcpy(H->elem[pp]->name,gai);break;
case2:
fflush(stdin);
printf("\n\t输入要修改后的地址:
”);gets(gai);
strcpy(H->elem[pp]->add,gai);
break;
default:
printf("\n\t输入错误!
");
}
}
else
printf("\n\t此人不存在,失败!
\n");
printf("\n\n\n\t按Esc键,返回主菜单”);
}
voidDelete(HashTable*&H,intc,Record*a)//删除
{
system("cls");
PR6();
fflush(stdin);
FRItel;
printf("\n\n\t输入要删除的:
”);
gets(tel);
inti=0;
while(strcmp(a[i].tel,tel)!
=O)
i++;
ss=i;
intp,pp;
p=HASH(tel);
pp=p;
while(H->elem[pp]!
=NULL&&bj(tel,H->elem[pp]->tel)==0)pp=collision(p,c);
if(H->elem[pp]!
=NULL&&bj(tel,H->elem[pp]->tel)==1){
H->elem[pp]=NULL;
H->count--;
}
else
printf(“\n\n\t\t对不起,无此人信息!
\n\n”);
printf("\n\t按Esc键,返回主菜单”);
}
voidList(Record*a,HashTable*H)//输出
{
system("cls");
PR8();
inti;
printf("\t\t\t\t\t联系地址\n\n");
for(i=0;iif(i!
=ss)
printf("\t\t%s\t%s\t\t%s\n\n",a[i].name,a[i].tel,a[i].add);
printf("\n\n\t\t\t按Esc键,返回主菜单”);
}
voidSave(Record*a)〃写入文件
{
FILE*fp;
Record*pp;
if((fp=fopen("D:
\\wo.txt","wb"))==NULL)
printf("\nFileopenerror");
pp=a;
fwrite(pp,sizeof(Record),NUM_BER,fp);
fclose(fp);
printf("\n\t按Esc键,返回主菜单");
}
voidLoad(Record*a)〃从文件读取
{
system("cls");
FILE*fp;
Record*pp;
pp=a;
PR9();
if((fp=fopen(("D:
\\wo.txt","rb"))==NULL)
printf("\nFileopenerror");
printf("\t\t\t\t联系地址\n\n");fread(pp,sizeof(Record),NUM_BER,fp);
for(inti=O;iprintf("\t%s\t%s\t\t%s\n\n",pp->name,pp->tel,pp->add);fclose(fp);
printf("\n\t按Esc键,返回主菜单");
}
intQuit()〃结束程序
{
intmai