设计任务
设计哈希表实现电话号码查找系统
- 设每个记录有下列数据项:电话号码、用户名、地址
- 从键盘输入个记录,分别以电话号码和用户名为关键字建立不同的哈希表
- 采用线性探测再散列的方法解决冲突
- 查找并显示给定电话号码的记录
- 查找并显示给定用户名的记录
主要算法功能
主要4个功能:
- 创建链表
- 查询(通过名字/电话)
- 显示
- 退出
以下是简易流程图:
代码
为了让主代码main.c看起来更加清晰,我把功能函数集成在一个头文件中hash.h。
代码里用不大好的英文注释,能懂9行
main.c文件
#include"hash.h"
int main()
{
char s[20];
int n,Fn;
int num;//contact number
Bridge head;//include namehash table and phonehash table
while(1)
{
Menu();
printf("Enter:");
scanf("%d",&n);
switch(n)
{
case 1:
printf("Enter number of contacts:");
scanf("%d",&num);
Fn=Fprime(num);//get next prime
head=Create(num);//creat link
Clean();
break;
case 2:
Query(head,Fn);
Clean();
break;
case 3:
ShowAll(head,Fn);//print all contacts
Clean();
break;
case 4:
printf("\nThank you for using my software!\n");
return 0;
}
}
}
hash.h文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAXNUMBER 100000
typedef struct node
{
char name[8];
char phone[12];
char adress[50];
int state;
struct node *next;
}contnode;
typedef struct
{
contnode *Hn;//head node of name
contnode *Hp;//head node of phone
}Bridge;
void Menu()
{
printf("\n----------Menu----------\n\n");
printf(" 1.Create contacts\n");
printf(" 2.Query contacts\n");
printf(" 3.Show all contacts\n");
printf(" 4.Exit\n");
printf("------------------------\n");
}
void Clean()//clear window
{
printf("\nClear window? (Y/N)\t");
getchar();//filter \n
if(getchar()=='Y')
system("cls");
}
void ShowAll(Bridge h,int n)//show all contacts
{
contnode *p=h.Hp;
printf("\nName\tPhone\t\tAdress");
printf("\n--------------------------------------\n");
while(n--)
{
if(p->state==1)
printf("%s\t%s\t%s\n",p->name,p->phone,p->adress);
p=p->next;
}
}
int Fprime(int n)//find next prime
{
int i,p=(n%2)?n+2:n+1;
while(p<=MAXNUMBER)
{
for(i=(int)sqrt(p);i>2;i--)
if(!(p%i))
break;
if(i==2)
break;
else
p+=2;
}
return p;
}
contnode* CreatTable(int num)//insert tail & init
{
contnode *p,*q,*h;
q=p=h=(contnode*)malloc(sizeof(contnode));
h->state=0;
while(num--)
{
p=(contnode*)malloc(sizeof(contnode));
strcpy(p->name,"\0");
strcpy(p->adress,"\0");
strcpy(p->phone,"\0");
p->state=0;
q->next=p;
q=p;
}
p->next=NULL;
free(p);
free(q);
return h;
}
int Ghashn(char *key,int num)//get hash name number
{
unsigned int h=0;
while(*key!='\0')
h=(h<<5)+*key++;
return h%num;
}
int Ghashp(char *key,int num)//get hash phone number
{
int i;
int sum=0;
for(i=6;i<=10;i++)
sum=sum*10+key[i]-'0';
return sum%num;
}
void HashTable(char *name,char *phone,char *adress,contnode *h,int flag,int size)//create table
{
int seat;
contnode *p=h;
if(flag)
seat=Ghashp(phone,size);
else
seat=Ghashn(name,size);
while(seat&&seat--)//Go to the designated location
p=p->next;
while(p->state!=0)//Linear Probing(if state==1 ,find the next one)
{
if(p->next==NULL)
{
p=h;
continue;
}
p=p->next;
}
strcpy(p->name,name);
strcpy(p->adress,adress);
strcpy(p->phone,phone);
p->state=1;
}
void show(contnode *n)//print the contact
{
printf("\nName\tPhone\t\tAdress");
printf("\n--------------------------------------\n");
printf("%s\t%s\t%s\n",n->name,n->phone,n->adress);
}
void FindSeat(contnode *h,int size,int flag)//find seat of number
{
char key[15];
int seat,bseat,f=1;
contnode *p=h;
printf("\nEnter key:");
scanf("%s",key);
if(flag)
seat=Ghashp(key,size);//find table number of phone
else
seat=Ghashn(key,size);//find table number of name
bseat=seat;
while(seat>0&&--seat)
p=p->next;
if(flag)
while(strcmp(p->phone,key)!=0)
{
if(p->next==NULL)//If to the end back to the head
{
f=1;
p=h;
}
if(f)
bseat++;
if(bseat>=size)//If steps are larger than size return
{
printf("\nSorry,not found!\n");
return;
}
p=p->next;
}
else
while(strcmp(p->name,key)!=0)
{
if(p->next==NULL)
{
f=1;
p=h;
}
if(f)
bseat++;
if(bseat>=size)
{
printf("\nSorry,not found!\n");
return;
}
p=p->next;
}
show(p);//print node
}
Bridge Create(int num)
{
int i;
contnode *Hp,*Hn;
Bridge h;
char name[8],adress[20],phone[12];
Hp=CreatTable(Fprime(num));//get head node
Hn=CreatTable(Fprime(num));
for(i=0;i<num;i++)
{
printf("\n%dst contact:",i+1);
printf("\nEnter name:");
scanf("%s",name);
printf("Enter phone:");
scanf("%s",phone);
printf("Enter adress:");
scanf("%s",adress);
HashTable(name,phone,adress,Hn,0,Fprime(num));//create hashtable by name
HashTable(name,phone,adress,Hp,1,Fprime(num));//create hashtable by phone
}
h.Hn=Hn;
h.Hp=Hp;
return h;
}
void Query(Bridge head,int size)
{
int n;
printf("\n-------Choose way-------\n");
printf("1.By Name\n");
printf("2.By Phone\n");
printf("------------------------\n");
printf("Enter:");
scanf("%d",&n);
switch(n)
{
case 1:FindSeat(head.Hn,size,0);
break;
case 2:FindSeat(head.Hp,size,1);
break;
}
}