#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR 0
#define OK 1
#define Size 21 // 指定质数(数组长度)
typedef struct{
char name[20];
char address[20];
char num[12];
}mul;
typedef struct{
mul data[20];
int size;
}Hashtable;
void init(Hashtable &h)
{
for(int i=0;i<Size;i++){
h.data[i].num[0]=0;//首位赋为0
}
h.size = Size;
}
// 判断电话簿是否为空
int kong(Hashtable &h){
for(int i=0;i<Size;i++){
if(h.data[i].num[0]!=0){
return ERROR;
}
}
return OK;
}
int HashSearch(Hashtable &h);
// 新存入的数的和是否已经被存储了
int c_t(Hashtable &h,int sum){
int m,n,sum1=0;
for(int k=0;k<Size;k++){ //循环整个数组
n = strlen(h.data[k].num);
if(h.data[k].num[0]!=0){
for(m=0;m<n;m++){
sum1=sum1+h.data[k].num[m]-'0';
}
if(sum1==sum){
printf("您输入的电话号码已经被存储,请重新输入\n\n");
HashSearch(h);
fflush(stdin);
return ERROR;
}
}
}
return OK;
}
// 寻址存数
int HashSearch(Hashtable &h)
{
char nu[12],na[20],add[50];
int i,p,j,y=0,boo=1;//nu关键字
int m,n,sum=0,sum1=0;
printf("请输入要存入的电话记录的姓名、地址和11位手机号码(用空格隔开)\n");
scanf("%s",na);
scanf("%s",add);
scanf("%s",nu);
n=strlen(nu); // 电话号的长度
if(n==11){
for(m=0;m<n;m++){
sum=sum+nu[m]-'0'; // 计算电话号码的总和进行存储
}
boo=c_t(h,sum); // 判断输入的数是否被存储了
if(boo){
j=sum%Size;//哈希函数
if(h.data[j].num[0]==0){
p=j;
h.size=j;
}else{
i=(j+1)%Size; // 向后探测一个位置
if(h.data[i].num[0]==0){
p=i;
h.size=i;
}
while(h.data[i].num[0]!=0 && i!=j) {
i=(i+1)%Size; //向后探测位置
if(h.data[i].num[0]==0){
p=i;
h.size=i;
break;
}
}
if (i==j){
printf("当前电话谱最多只能实现 %d 个数据存储\n",Size);
return ERROR;
}
}
strcpy(h.data[p].num,nu); // 把存入的数据放入定义的数组指定位置
strcpy(h.data[p].address,add);
strcpy(h.data[p].name,na);
printf("存入数据 %d 号位置: %s %s %s\n",h.size,h.data[p].name,h.data[p].address,h.data[p].num);
}
}else{
printf("\n!!!请输入11位手机号码!!!\n");
HashSearch(h);
}
return OK;
}
// 批量存入电话记录
int pl_HashSearch(Hashtable &h){
int n=0;
printf("请输入您要添加电话记录的条数:");
scanf("%d",&n);
if(1<n&&n<21){
for(int i=0;i<n;i++){
HashSearch(h);
}
}else{
printf("\n您存入的条数大于20条 或者小于2条\n\n");
pl_HashSearch(h);
}
return OK;
}
// 打印所有记录
void disp(Hashtable &h)
{
printf("电话簿中电话记录如下:\n");
for(int i=0;i<Size;++i){
if(h.data[i].num[0]){
printf("%d号位置\n姓名:%s 地址:%s 电话:%s\n",i,h.data[i].name,h.data[i].address,h.data[i].num);
}
}
}
// 哈希查找
int hash_kind(Hashtable h){
char num[12];
int i,j,y=0;//nu关键字
int m,n,sum=0;
printf("请输入您要在电话簿中查找的电话号码:\n");
scanf("%s",&num);
n=strlen(num); // 电话号的长度
for(m=0;m<n;m++){
sum=sum+num[m]-'0'; // 计算电话号码的总和进行存储
}
j=sum%Size;//哈希函数
if(strcmp(h.data[j].num,num)==0){ // 探测查找
printf("您要查找的相关信息:%d号位置: \n姓名:%s\n地址:%s\n电话号码:%s\n",j,h.data[j].name,h.data[j].address,h.data[j].num);
}
else{
i=(j+1)%Size;
while(h.data[i].num[0]!=0 && i!=j) {
if(strcmp(h.data[i].num,num)==0){
printf("您要查找的相关信息:%d号位置 : \n姓名:%s\n地址:%s\n电话号码:%s\n",i,h.data[j].name,h.data[j].address,h.data[j].num);
break;
}
i=(i+1)%Size; //向后探测一个位置
}
if(h.data[i].num[0]==0){
printf("\n(嘟。。)当前号码谱没有此号码!!查无此人!!查无此人!!\n");
return ERROR;
}
}
return OK;
}
//操作菜单
void OperateMenu(){
printf("\n\n--------------请选择元素处理方式---------\n\n");
printf("注:电话号应为 11 位\n\n");
printf("0> :退出\n\n");
printf("1>: 存入电话号\n\n");
printf("2>: 批量存入电话号\n\n");
printf("3>: 哈希查找电话号\n\n");
printf("4>: 显示电话簿\n\n");
printf("请选择对元素的处理:");
}
void main(){
int w=0,k,boo=1,i=1,e=0;
Hashtable h;
printf("注:此测试过程输入值应全为数字\n\n");
printf("进入号码簿存储请输入:'1'\n\n");
printf("退出请选择'0'或 其它!!\n\n");
printf("请选择:");
scanf("%d",&w);
if(w==1){
init(h);
OperateMenu();
scanf("%d",&k);
while(k){
switch(k){
case 0:break;
case 1:boo=HashSearch(h);
if(boo)
printf("存入成功!!\n");
else
printf("存入失败!!\n");
break;
case 2:boo=pl_HashSearch(h);
if(boo)
printf("批量存入成功!!\n");
else
printf("批量存入失败!!\n");
break;
case 3:boo=kong(h);
if(boo==1){
printf("\n!!当前电话簿为空!!\n");
}else{
boo=hash_kind(h);
if(boo)
printf("哈希查找成功!!\n");
else
printf("哈希查找失败!!\n");
}
break;
case 4:
boo=kong(h);
if(boo==1){
printf("\n!!当前电话簿为空!!\n");
}else{disp(h); }break;
}
OperateMenu();
scanf("%d",&k);
}
}
}