1 .需求分析
• 为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的电话与地址。设计散列表存储,设计并实现通讯录查找系统。
1.基本要求
• (1)每个记录有下列数据项:电话号码、用户名、地址;
• (2)从键盘输入各记录,分别以电话号码为关键字建立散列表;
• (3)采用二次探测再散列法解决冲突;
• (4)查找并显示给定电话号码的记录;
• (5)通讯录信息文件保存。
• 2.重点、难点
• 重点:
• (1)通过实验深入理解哈希表既是一种存储形式,又是一种查找方法;
• (2)哈希表的构造;
• (3)哈希冲突方案的设计。
• 难点:哈希表的构造与哈希冲突方案的设计
(1) 输入的形式和输入值的范围;
(2) 输入三个字符串:
分别是电话号码,姓名,地址,每行一个数据
字符串长度适当
如:
15545871414
小明
安徽合肥
(3) 输出的形式;
输入联系人信息,每行包括一个联系人的姓名电话地址
如:
某某 15574157841 安徽合肥
(4) 程序所能达到的功能。
1:
输入联系人,支持多组输入;
并且通过电话号码为关键字,用二次再散列法寻找地址储存在哈希表中。
2:
查找联系人信息,可以通过电话号码,姓名,地址三种方式为关键字进行查找。
3:
删除联系人
4:
修改联系人信息。
5:显示通讯录
6:把通讯录写入文件储存。
2. 概要设计
(1) 数据结构
用结构体存储每个联系人的信息
struct list
{
char a[12];
char name[15];
char add[15];
intf=0;
};
f为储存标志,若为1,表示该联系人存在哈希表中
用连续的内存空间构建哈希表
struct sqstack
{
struct list *base;
inti;
};
(2)程序模块
1:
构建二次再散列:
int i;
for(i=1;i<25;i++)
d[2*i]=-1*i*i;
for(i=1;i<25;i++)/*构造二次再散列*/
d[i+i-1]=i*i;
2:主菜单:
void interface()
{
inti;
printf("********************\n");
printf("* 请输入操作指令\n*\n* 1:输入通讯录\n* 2:显示通讯录\n* 3:查找联系人\n* 4:删除联系人\n* 5:修改联系人信息\n* 6:保存到文件\n* 0:结束程序\n");
printf("********************\n");
scanf("%d",&i);
switch(i)
{
case 0:return ;break;
case 1:shuru();break;
case 2:print();break;
case 3:seach();break;
case 4:del();break;
case 5:change();break;
case 6:write();break;
};
}
3:输入
void shuru()
4:存入哈希表,采用二次探测再散列法解决冲突;
void store(char *a,char *name,char *add)
5:查找联系人,支持姓名电话地址三个关键字的查找
void seach();
6:修改联系人信息
void change()
7:删除联系人
Void del();
8:将联系人信息写入文件储存;
void write()
代码:
#include
#include
#include
#include
#include
using namespace std;
int d[50];/*再散列*/
struct list
{
char a[12];
char name[15];
char add[15];
int f=0;
};
struct sqstack
{
struct list *base;
int i;
};
struct sqstack S;
void store(char *a,char *name,char *add)
{
int key;
key=int(a[0])+int(a[3])+int(a[7]);/*以电话号码的第1,4,8位作为关键字构造哈希函数*/
S.i=key%20;
int j=1;
while(true)
{
if((S.base+S.i)->f==0)
{
strcpy((S.base+S.i)->a,a);
strcpy((S.base+S.i)->name,name);
strcpy((S.base+S.i)->add,add);
(S.base+S.i)->f=1;
break;
}
S.i=(key%20+d[j])%20;
j++;
}
}
void shuru()
{
void interface();
cout<<"请输入:\n例如:\n15556931615\n小王\n安徽省合肥市\n输入0结束\n";
char a[12];
char name[15];
char add[15];
while(true)
{
scanf("%s",a);
if(a[0]=='0')
break;
scanf("%s",name);
scanf("%s",add);
printf("%s已保存\n",name);
store(a,name,add);/*将输入保存到哈希表*/
}
interface();
}
void print()
{
void interface();
int i;
printf("姓名 电话号码 地址\n");
for(i=0;i<20;i++)
{
if((S.base+i)->f==1)
{
printf("%s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
}
}
interface();
}
void seach()
{
void interface();
int i;
int ff=0;
int b;
char a[15];
printf("输入1按电话号码查找,输入2按姓名查找,输入3按地址查找\n");
scanf("%d",&b);
switch(b)
{
case 1:printf("请输入电话号码\n");
scanf("%s",a);
for(i=0;i<20;i++)
if(strcmp(a,(S.base+i)->a)==0)
{
printf("%s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
ff=1;
}
if(ff==0)
printf("找不到该用户\n");
break;
case 2:printf("请输入姓名\n");
scanf("%s",a);
for(i=0;i<20;i++)
if(strcmp(a,(S.base+i)->name)==0)
{
printf("%s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
ff=1;
}
if(ff==0)
printf("找不到该用户\n");
break;
case 3:printf("请输入地址\n");
scanf("%s",a);
for(i=0;i<20;i++)
if(strcmp(a,(S.base+i)->add)==0)
{
printf("%s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
ff=1;
}
if(ff==0)
printf("找不到该用户\n");
break;
}
interface();
}
void del()
{
void interface();
int i;
int ff=0;
int b;
char a[15];
printf("输入1按电话号码删除,输入2按姓名删除,输入3按地址删除\n");
scanf("%d",&b);
switch(b)
{
case 1:printf("请输入电话号码\n");
scanf("%s",a);
for(i=0;i<20;i++)
if(strcmp(a,(S.base+i)->a)==0)
{
(S.base+i)->f=0;
printf("已删除: %s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
ff=1;
}
if(ff==0)
printf("找不到该用户\n");
break;
case 2:printf("请输入姓名\n");
scanf("%s",a);
for(i=0;i<20;i++)
if(strcmp(a,(S.base+i)->name)==0)
{
(S.base+i)->f=0;
printf("已删除: %s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
ff=1;
}
if(ff==0)
printf("找不到该用户\n");
break;
case 3:printf("请输入地址\n");
scanf("%s",a);
for(i=0;i<20;i++)
if(strcmp(a,(S.base+i)->add)==0)
{
(S.base+i)->f=0;
printf("已删除: %s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
ff=1;
}
if(ff==0)
printf("找不到该用户\n");
break;
}
interface();
}
void change()
{
void interface();
int i;
int ff=0;
int b;
char a[15];
printf("请输入姓名\n");
scanf("%s",a);
for(i=0;i<20;i++)
if(strcmp(a,(S.base+i)->name)==0)
{
printf("您要修改的是: %s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
printf("请输入新信息\n");
scanf("%s",(S.base+i)->a);
scanf("%s",(S.base+i)->name);
scanf("%s",(S.base+i)->add);
printf("已修改成: %s %s %s\n",(S.base+i)->name,(S.base+i)->a,(S.base+i)->add);
ff=1;
}
if(ff==0)
printf("找不到该用户\n");
interface();
}
void write()
{
void interface();
int i=0;
FILE *fp;
if((fp=fopen("通讯录.txt","wb"))==NULL)
{
printf("open file error\n");
exit(1);
}
for(i=0;i<=20;i++)
{
int ch=32;
if((S.base+i)->f==1)
{
fprintf(fp,"%s",(S.base+i)->name);fputc(ch,fp);
fprintf(fp,"%s",(S.base+i)->a);fputc(ch,fp);
ch=10;
fprintf(fp,"%s",(S.base+i)->add);fputc(ch,fp);
}
}
fclose(fp);
interface();
}
void interface()
{
int i;
printf("********************\n");
printf("* 请输入操作指令\n*\n* 1:输入通讯录\n* 2:显示通讯录\n* 3:查找联系人\n* 4:删除联系人\n* 5:修改联系人信息\n* 6:保存到文件\n* 0:结束程序\n");
printf("********************\n");
scanf("%d",&i);
switch(i)
{
case 0:return ;break;
case 1:shuru();break;
case 2:print();break;
case 3:seach();break;
case 4:del();break;
case 5:change();break;
case 6:write();break;
};
}
int main()
{
system("color 70"); //可以写成 red 调出颜色组
S.base=(struct list *)malloc(20*sizeof(struct list));
printf(" ****************欢迎使用通讯录查询系统*********************\n\n");
system("date /T");
system("TIME /T");
int i;
for(i=1;i<25;i++)
d[2*i]=-1*i*i;
for(i=1;i<25;i++)/*构造二次再散列*/
d[i+i-1]=i*i;
interface();
}
运行环境:codeblocks cpp
主界面:
输入联系人,支持批量输入
构建哈希表,允许电话号码重复
显示联系人信息:
可以再增加新的联系人:
查找联系人信息:
可以支持姓名,电话,地址三个关键字的查找
删除联系人
可以按照电话姓名地址删除
修改联系人信息::
写文件:
创建文件通讯录.txt
并且将联系人存入
如图: