#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define Size 11
typedef struct{
char name[30];
char address[20];
//float num;
char num[30];
int c;//统计比较次数
}record;
typedef struct{
record data[Size];
int count;
int size;
}Hashtable;
void init(Hashtable &h)
{
for(int i=0;i<Size;i++)
{h.data[i].num[0]=0;
h.data[i].c=0;}//!
h.size=Size;
h.count=0;
}
int exchange(char str[])
{
int i,n,sum=0;
n=strlen(str);
for(i=0;i<n;i++)
sum=sum+str[i]-'0';
return sum;
}
int HashSearch1(Hashtable &h,char *str,int &p) //线性探测
{
int i,j,k=exchange(str);
j=k%Size;
if(strcmp(str,h.data[j].num)==0)
{
return j;
h.data[j].c++;//!
}//没有发生冲突,比较一次查找成功
if(h.data[j].num[0]==0)
{
p=j;
return 0;
}
else
{
h.data[j].c++;//!
i=(j+1)%Size;//第1次解决冲突
while(h.data[i].num[0]!=0&&i!=j)
{
if(strcmp(str,h.data[i].num)==0)
{
h.data[j].c++;//!
return i;
}//发生冲突,比较若干次查找成功
i=(i+1)%Size; //向后探测一个位置
}
if (i==j)
printf("溢出\n");
else
{
p=i;
h.data[j].c++;//!
return 0;//查找不成功
}
}
}
int HashSearch2(Hashtable &h,char *str,int &p)
{
int i,j,t=1,d=1;
int k=exchange(str);
j=k%Size;
if(strcmp(str,h.data[j].num)==0)
{
h.data[j].c++;//!
return j;
} //没有发生冲突,比较一次查找成功
if(h.data[j].num[0]==0)
{
p=j;
return 0;
}
else
{
i=(j+d)%Size;//第1次解决冲突
while(h.data[i].num[0]!=0&&i!=j)
{
if(strcmp(str,h.data[i].num)==0)
{
h.data[j].c++;//!
return i;
}
if(t>0)
t=-1*d*d;
else
{
d=d+1;
t=-1*d*d ;
}
i=(j+t+Size)%Size; //探测一个新的位置
while(i<0)
{
h.data[j].c++;//!
i=(i+Size)%Size;
} }
if (i==j)
printf("溢出\n");
else
{
p=i;
h.data[j].c++;//!
return 0;//查找不成功时插入
}
}
}
void disp(Hashtable h)
{
printf("电话簿中所有电话记录如下:\n");
for(int i=0;i<Size;i++)
{
if(h.data[i].num[0])
printf("-.%7s s %s\n",i,h.data[i].name,h.data[i].address,h.data[i].num);
}
}
//
int compasl(Hashtable h)
{
int sum=0;
for(int i=0;i<Size;i++)
sum+=h.data[i].c;
return sum;
}
int menu()
{
int num;
while(1)
{
system("cls");
printf("\n---------电话管理系统模拟(哈希表实现)---------\n");
printf("\n**********************************************\n");
printf("\n 0.退出电话簿 1.已存在的电话记录 \n");
printf("\n 2.添加记录到电话簿1 3.添加记录到电话簿2 \n");
printf("\n 4.查找电话簿1通讯人 5.查找电话簿2通讯人 \n");
printf("\n 6.电话簿1查找ASL 7.电话簿2查找ASL \n");
printf("\n**********************************************\n");
printf("\n----------------------------------------------\n");
printf("\n请您选择操作(0--7):\n");
scanf("%d",&num);
if(num<0||num>7)
printf("您的选择有误,请重新选择!\n");
break;
}
return num;
}
void main()
{
Hashtable h1,h2;
int i,j,n,a,m,flag=1;
char num[30];
char name[30],address[50];
init(h1);init(h2);
while(1)
{
j=menu();
switch(j){
case 0:printf("(@ @) 谢谢使用,再见! (^ ^)\n");
exit(0);
getch();
break;
case 1:
if(flag){
FILE *fp;
if((fp=fopen("1234.txt","r+"))==NULL)
{
puts("成功导入电话记录!");
exit(0);
}
fscanf(fp,"%d",&n);
for(i=0;i<n;i++)
{
fscanf(fp,"%s%s%s",name,address,num);
HashSearch1(h1,num,a);
strcpy(h1.data[a].num,num);
strcpy(h1.data[a].address,address);
strcpy(h1.data[a].name,name);
h1.count++;
}
puts("\t成功将电话记录导入电话簿1!");
disp(h1);
fclose(fp);
if((fp=fopen("1234.txt","r+"))==NULL)
{
puts("导入电话记录失败");
exit(0);
}
fscanf(fp,"%d",&n);
for(i=0;i<n;i++)
{
fscanf(fp,"%s%s%s",name,address,num);
HashSearch2(h2,num,a);
strcpy(h2.data[a].num,num);
strcpy(h2.data[a].address,address);
strcpy(h2.data[a].name,name);
h2.count++;
}
puts("\t成功将电话记录导入电话簿2!");
disp(h2);
fclose(fp);
printf("按任意键继续!\n");
getch();}
flag=0;
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++;
}
}
disp(h1);
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++;
}
}
disp(h2);
printf("按任意键继续!\n");
getch();
break;
case 4:disp(h1);
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");
getch();
break;
case 5:disp(h2);
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");
getch();
break;
case 6:printf("在电话簿1中查找的ASL为:\n");
printf("%d %d\n",compasl(h1),h1.count);
printf("按任意键继续!\n");
getch();
break;
case 7:printf("在电话簿2中查找的ASL为:\n");
printf("%d %d\n",compasl(h2),h2.count);
printf("按任意键继续!\n");
getch();
break;
}
}
}
下面是课程设计的报告:
一、课程设计的目的与要求
二、设计正文
(一)
(二)
分析:由于题目要求以电话号码为关键字建表,考虑到电话号码长短不一,如果直接以表示电话号码的字符串为关键字,可能会造成一定的麻烦。故而,利用一个函数将表示电话号码的字符串转换成其相应的数字,然后把这些数字之和作为关键字即可将上述麻烦解除。
(三)
int HashSearch2(Hashtable &h,char *str,int &p)
void disp(Hashtable h)
}ADT hashtable
将每个人的信息作为一条记录,包括电话号码、用户名、地址,还有一个整型变量用来记录冲突的次数,便于计算ASL,然后哈希表由记录数组、表现存量、容量组成,具体数据类型见下:
typedef struct {
typedef struct{
}Hashtable;
各函数之间的调用关系是:
主函数main() |
菜单函数menu() |
线性探测解决冲突hashserch1() |
查找用户 |
考察ASL1 |
二次探测解决冲突hashsearch2() |
查找用户 |
考察ASL |
显示电话簿disp() |
(四)
}
int HashSearch2(Hashtable &h,char *str,int &p) //二次探测
{
(五)
本实验的运行环境是VC++。按照要求,应该事先导入一些记录,以下为本实验的测试数据:
4
侯进斌 北京 6627584
王璐 太原 6650370
(六)
(七)测试数据
同理还可以查看电话簿2的这项功能:
如果您想结束操作,直接选0,即可退出该系统:
三、课程设计总结或结论
1.完成的工作
该实验的所有要求:哈希表的创建,用两种不同的方法处理冲突,考察各种处理冲突方法的ASL;
2.未完成的工作
无;
3.所需做的改进
应该尝试更多的处理冲突的方法
一些代码的效率很低,有待改进
四、参考文献
《数据结构》(C语言版)