一、需求分析 1
二、概要设计 2
三、详细设计 3-8
四、调试分析 9-11
五、运行结果 12-21
六、参考文献 21
七、附录 21-47
一、需求分析
1.设计目的
电话簿是人们用来记录亲人朋友电话的工具,发展至现在已经不只是传统的纸制本子,电脑,手机等电子产品也都具备了记录的功能。电话簿作为手机的基本功能之一,每天都被我们频繁地使用着,根据手机功能使用调查显示,有八成以上的消费者使用手机电话簿功能。
本次设计的电话簿是一款绝对专业的个人通讯信息管理软件,本次设计的电话簿就是为了方便消费者以不同的方式查找和储存电话。电话簿中储存方式大致可分为两类,一类是按照姓名来储存入电话簿,另一种是按照电话号码来储存入电话簿。为了更贴近用户需求,本次设计的电话簿包含了以上两种储存和查找方式。
2.程序所能达到的功能
(1)用户可以通过键盘输入来选择以号码或者名字为关键字建表。
(2)从键盘输入要插入的的记录,分别以线性探测法和二次探测法来解决冲突。
(3)用户通过输入电话号码查找,可以给出电话号码的记录。
(4)用户通过输入用户名查找,可以给出电话号码的记录。
(5)在哈希函数确定的前提下,分别以线性探测法和二次探测法来解决冲突,并计算平均查找长度。
(6)展示表中所有的电话记录。
二、概要设计
本系统旨在通过建立哈希表实现电话簿录入、查询电话记录、展示所有电话记录等功能,帮助用户方便的处理电话记录。
简单思路:
建立表:
对于通过电话号码和地址为关键字建立哈希表,使用除留余数法。
解决冲突:
分别使用二次探测法和线性探测法来解决冲突。
三、详细设计
3.1建立哈希表(实例)的存储结构
将每个人的信息作为一条记录,包括电话号码、用户名、地址,还有一个整型变量用来记录冲突的次数,便于计算ASL,然后哈希表由记录数组、表中现存量、表容量组成,具体数据类型见下:
address[20] 地址
name[30]; 名字
num[30] 电话号码
int c; 查找次数
结构体 {
char name[30];名字
char address[20];地址
char num[30];电话号码
int c;查找次数
}record;
结构体{
record data[Size];哈希表
int count;现在有的数据个数
int size;哈希表长度
} Hashtable;
3.2建立哈希表(实例)的操作
为了实现上述程序的功能,需要定义下列抽象数据类型:
ADT hashtable {
数据对象:哈希表中存储的个条电话记录;
数据关系:表中相邻元素之间有前去和后继的关系;
基本操作:
init(Hashtable &h)
操作结果:初始化了哈希表
int exchange(char str[])
操作结果:请关键字从char型转为int;
int HashSearch1(Hashtable &h,char *str,int &p)
操作结果:在表中以电话号码线性探测数据,返回数据插入位置;
int HashSearch1_n(Hashtable &h,char *str,int &p)
操作结果:在表中以姓名线性探测数据,返回数据的插入位置;
int HashSearch2(Hashtable &h,char *str,int &p)
操作结果:在表中以电话号码二次探测数据,返回数据的插入位置;
int HashSearch2(Hashtable &h,char *str,int &p)
操作结果:在表中以姓名二次探测数据,返回数据的插入位置;
void disp(Hashtable h)
操作结果:显示出哈希表中储存的电话记录;
}ADT hashtable
3.3程序具体实行流程
(1)主菜单和次菜单的进入和退出。
利用while(1){}和swith语句来实现主菜单和次菜单的转换
while(1)语句可以让程序一直运行,每结束一次操作后重新再来;
swith(主菜单)语句在主菜单选择建立哈希表的关键字;
swith(次菜单)语句在次菜单选择电话簿功能;
cc=menu_1();重新选择swith(主菜单);
(2)建立哈希函数——采取除留余数法
第一步:把字符串先转化为一个整数。
int exchange(char str[]) 使用关键字的哈希函数,各项转化为整数型相加;
第二步:与哈希表的最大容量使用除留余数法得到哈希函数。
j=k%Size;
(3)解决冲突——线性探测法和二次探测法
二次探测法:
(4)计算ASL
int c;查找次数
int count;现在有的数据个数
结构体中定义了c来计录每一个记录的比较次数,方便最后求ASL。
ASL=
四、调试分析
》》》》》》
主程序
void main()
{
Hashtable h1,h2,h3,h4;
int i,j,cc,n,a,m,flag=1,k=5;
char num[30];
char name[30];
char address[20];
init(h1);
init(h2);
init(h3);
init(h4);
cc=menu_1();
while(1){
switch(cc){
case 1:
system("cls");
j=menu_2();
switch(j){
case 0:
printf("(@ @) 谢谢使用,再见! (^ ^)\n");
exit(0);
getch();
break;
//******
case 1:
//重新选择关键字
cc=menu_1();
break;
//******
case 2:
printf("添加电话记录到电话簿1:\n");
printf("请输入您要添加电话记录的数目:\n");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("请输入第%d条电话记录的姓名、地址和电话号码(用空格隔开)\n",i+1);
scanf("%s%s%s",name,address,num);
if(HashSearch1(h1,num,a))
{
printf("已存在");
i--;
}
else
{
strcpy(h1.data[a].num,num);
strcpy(h1.data[a].address,address);
strcpy(h1.data[a].name,name);
h1.count++;
printf("插入成功");
}
}
printf("按任意键继续!\n");
getch();
break;
case 3:
printf("添加电话记录到电话簿2:\n");
printf("请输入您要添加电话记录的数目\n");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("请输入第%d条电话记录的姓名、地址和电话号码(用空格隔开)\n",i+1);
scanf("%s%s%s",name,address,num);
if(HashSearch2(h2,num,a))
{
printf("已存在");
i--;
}
else
{
strcpy(h2.data[a].num,num);
strcpy(h2.data[a].address,address);
strcpy(h2.data[a].name,name);
h2.count++;
printf("插入成功");
}
}
printf("按任意键继续!\n");
getch();
break;
case 4:
printf("请输入您要在电话簿1中查找的人的电话号码:\n");
scanf("%s",num);
printf("\n");
if(m=HashSearch1(h1,num,a))
{
printf("查找的结果为:\n");
printf("您要查找的人的姓名、地址和电话号码分别为:\n%s,%s,%s\n",h1.data[m].name,h1.data[m].address,h1.data[m].num);
}
else
printf("对不起,没有您要找的人!\n");
printf("按任意键继续!\n");
printf("按任意键继续!\n");
getch();
break;
case 5:
printf("请输入您要在电话簿2中查找的人的电话号码:\n");
scanf("%s",num);
printf("\n");
if(m=HashSearch2(h2,num,a))
{
printf("查找的结果为:\n");
printf("您要查找的人的姓名、地址和电话号码分别为:\n%s,%s,%s\n",h2.data[m].name,h2.data[m].address,h2.data[m].num);
}
else
printf("对不起,没有您要找的人!\n");
printf("按任意键继续!\n");
printf("按任意键继续!\n");
getch();
break;
case 6:
printf("电话簿1:\n");
disp(h1);
printf("在电话簿1中查找的ASL为:\n");
printf("%d / %d\n",compasl(h1),h1.count);
printf("按任意键继续!\n");
getch();
break;
case 7:
printf("电话簿2:\n");
disp(h2);
printf("在电话簿2中查找的ASL为:\n");
printf("%d / %d\n",compasl(h2),h2.count);
printf("按任意键继续!\n");
getch();
break;
default: printf("您的选择有误,请重新选择!\n");
break;
}
break;
case 2:
system("cls");
j=menu_2();
switch(j){
case 0:
printf("(@ @) 谢谢使用,再见! (^ ^)\n");
exit(0);
getch();
break;
case 1:
//重新选择关键字
cc=menu_1();
break;
//******
case 2:
printf("添加电话记录到电话簿1:\n");
printf("请输入您要添加电话记录的数目:\n");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("请输入第%d条电话记录的姓名、地址和电话号码(用空格隔开)\n",i+1);
scanf("%s%s%s",name,address,num);
if(HashSearch1_n(h3,name,a))
{
printf("已存在");
i--;
}
else
{
strcpy(h3.data[a].num,num);
strcpy(h3.data[a].address,address);
strcpy(h3.data[a].name,name);
h3.count++;
printf("插入成功");
}
}
printf("按任意键继续!\n");
getch();
break;
case 3:
printf("添加电话记录到电话簿2:\n");
printf("请输入您要添加电话记录的数目\n");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("请输入第%d条电话记录的姓名、地址和电话号码(用空格隔开)\n",i+1);
scanf("%s%s%s",name,address,num);
if(HashSearch2_n(h4,name,a))
{
printf("已存在");
i--;
}
else
{
strcpy(h4.data[a].num,num);
strcpy(h4.data[a].address,address);
strcpy(h4.data[a].name,name);
h4.count++;
printf("插入成功");
}
}
printf("按任意键继续!\n");
getch();
break;
case 4:
printf("请输入您要在电话簿1中查找的人的xm:\n");
scanf("%s",name);
printf("\n");
if(m=HashSearch1_n(h3,name,a))
{
printf("查找的结果为:\n");
printf("您要查找的人的姓名、地址和电话号码分别为:\n%s,%s,%s\n",h3.data[m].name,h3.data[m].address,h3.data[m].num);
}
else
printf("对不起,没有您要找的人!\n");
printf("按任意键继续!\n");
printf("按任意键继续!\n");
getch();
break;
case 5:
printf("请输入您要在电话簿2中查找的人的姓名:\n");
scanf("%s",name);
printf("\n");
if(m=HashSearch2_n(h4,name,a))
{
printf("查找的结果为:\n");
printf("您要查找的人的姓名、地址和电话号码分别为:\n%s,%s,%s\n",h4.data[m].name,h4.data[m].address,h4.data[m].num);
}
else
printf("对不起,没有您要找的人!\n");
printf("按任意键继续!\n");
printf("按任意键继续!\n");
getch();
break;
case 6:
printf("电话簿1:\n");
disp(h3);
printf("在电话簿1中查找的ASL为:\n");
printf("%d / %d\n",compasl(h3),h3.count);
printf("按任意键继续!\n");
getch();
break;
case 7:
printf("电话簿2:\n");
disp(h4);
printf("在电话簿2中查找的ASL为:\n");
printf("%d / %d\n",compasl(h4),h4.count);
printf("按任意键继续!\n");
getch();
break;
default: printf("您的选择有误,请重新选择!\n");
break;
}
break;
default: printf("您的选择有误,请重新选择!\n");
}
}
}
源码地址