#ifndef _SAN_H_
#define _SAN_H_
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#pragma warning(disable:4996)
#define NAME_SIZE 20
#define TEL_SIZE 20
#define ADD_SIZE 20
#define HASHSIZE 37
#define MAXSIZE 100
#define MAX_SIZE 20
typedef struct
{
char name[NAME_SIZE];
char tel[TEL_SIZE];
char add[ADD_SIZE];
}Record;
typedef struct
{
Record *elem[HASHSIZE]; //数据元素储存地址
int count; //当前元素个数
int size; //当前容量
}Hashtable;
typedef char NA[MAX_SIZE];
int num_ = 0;
Record a[MAXSIZE];
Hashtable H;
void Menu();
void Getin();
void ShowInfromation();
void CreatHash();
void SearHash(int c);
void Menu()
{
printf("#############################################\n");
printf("#### 1.添加用户信息 #######\n");
printf("#### 2.读取用户信息 #######\n");
printf("#### 3.以电话号码为关键字建表 #######\n");
printf("#### 4.查找并显示电话号码的记录 #####\n");
printf("#### 5.退出 #######\n");
printf("#############################################\n");
printf("请输入你想要进行的操作;\n");
}
void Getin()
{
int i = 0;
int num;
printf("请输入需要添加的个数:");
scanf("%d", &num);
for (i = num_; i < num + num_; i++){
printf("请输入第%d个用户名:", i + 1);
scanf("%s", a[i].name);
printf("请输入第%d个电话号码:", i + 1);
scanf("%s", a[i].tel);
printf("请输入第%d个住址:", i + 1);
scanf("%s", a[i].add);
}
num_ = num_ + num;
}
void ShowInfromation()
{
int i = 0;
for (i = 0; i < num_; i++){
printf("\n第%d个用户:\n姓名:%s\n电话:%s\n住址:%s\n", i + 1, a[i].name, a[i].tel, a[i].add);
}
}
int Hash(NA str)
{//电话号码建表的散列函数
//用除留余数法构造散列函数
//并返回模值
return atoi(str) % HASHSIZE; //把字符串转换成整型的函数.
}
static int collision(int p, int c) //c=0 p=1
{//冲突处理函数,采用二次探测再散列法解决冲突
int i, q;
i = c / 2 + 1; //1
while (i<HASHSIZE)
{
if (c % 2 == 0)
{
c++;//1
q = (p + i*i) % HASHSIZE;//0
if (q >= 0)
return q;
else
i = c / 2 + 1;
}
else
{
q = (p - i*i) % HASHSIZE;
c++;
if (q >= 0)
return q;
else
i = c / 2 + 1;
}
}
return -1;
}
void CreatHash()
{
int i, p = 0, c, pp;
for (i = 0; i < num_; i++){
c = 0;
p = Hash(a[i].tel);
pp = p;
while (H.elem[pp] != NULL)
{
pp = collision(p, c++);
if (pp < 0)
{
printf("第%d个记录无法解决冲突\n", i + 1);
continue;
}
}
H.elem[pp] = &(a[i]);
printf("第%d个冲突为%d\n", i + 1, c);
}
printf("\n建表完成!\n此散列表的容量为:%d\n", HASHSIZE);
}
void SearHash(int c)
{//在通讯录里查找电话号码关键字,若查找成功,显示信息//c用来记录冲突次数,查找成功时显示冲突次数
NA tele;
int p, pp;
printf("\n请输入要查找记录的电话号码:\n");
scanf("%s", tele);
p = Hash(tele);
pp = p;
while (strcmp(tele, H.elem[pp]->tel) == -1){
pp = collision(p, c);
}
if (strcmp(tele, H.elem[p]->tel) != -1)
{
printf("\n查找成功!\n查找过程冲突次数为%d.以下是您需要要查找的信息:\n", c);
printf("姓 名:%s\n电话号码:%s\n联系地址:%s\n", H.elem[pp]->name, H.elem[pp]->tel, H.elem[pp]->add);
}
else
printf("\n此人不存在,查找不成功!\n");
}
#endif
#include "san.h"
int main()
{
int key;
int quit = 1;
int c = 0;
while (quit)
{
Menu();
scanf("%d", &key);
switch (key)
{
case 1:
Getin();
break;
case 2:
ShowInfromation();
break;
case 3:
CreatHash();
break;
case 4:
SearHash(c);
break;
case 5:
quit = 0;
break;
default:
printf("输入有误,请重新输入!");
break;
}
}
system("pause");
return 0;
}