1.问题描述:为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的电话与地址。设计散列表存储,设计并实现通讯录查找系统。
2.基本要求
(1)每个记录有下列数据项:电话号码、用户名、地址;
(2)从键盘输入各记录,分别以电话号码为关键字建立散列表;
(3)采用二次探测再散列法解决冲突;
(4)查找并显示给定电话号码的记录;
(5)通讯录信息文件保存。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int d[50];/*再散列*/
struct list
{
char a[12];
char name[15];
char add[15];
int f ;
};
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;
(S.base+S.i)->f=0;
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 caidan();
printf("请输入:\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);/*将输入保存到哈希表*/
}
caidan();
}
void print()
{
void caidan();
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);
}
}
caidan();
}
void seach()
{
void caidan();
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;
}
caidan();
}
void del()
{
void caidan();
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;
}
caidan();
}
void change()
{
void caidan();
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");
caidan();
}
void write()
{
void caidan();
int i=0;
FILE *fp;
if((fp=fopen("通讯录.txt","wb"))==NULL)
{
printf("文件打开失败\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);
printf("已保存\n");
caidan();
}
void caidan()
{
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;
};
}
void main()
{
system("color 70"); //可以写成 red 调出颜色组
S.base=(struct list *)malloc(20*sizeof(struct list));
printf(" ****************欢迎使用通讯录查询系统*********************\n\n");
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;
caidan();
}
建立链表存储信息,结构体中为三个字符数组,分别存储电话号码,姓名,地址,构建哈希表,根据电话号码的结构取电话号码的第一,四,八位和为关键字,冲突解决采用二次探测再散列,di=1^2,-1^2,2^2.-2^2…….删除和更改采用标记覆盖的方法,字符串比较。