哈希表实现电话号码查找系统

设计任务

设计哈希表实现电话号码查找系统

  1. 设每个记录有下列数据项:电话号码、用户名、地址
  2. 从键盘输入个记录,分别以电话号码和用户名为关键字建立不同的哈希表
  3. 采用线性探测再散列的方法解决冲突
  4. 查找并显示给定电话号码的记录
  5. 查找并显示给定用户名的记录

主要算法功能

主要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;
	}
}

#include #include #include using namespace std; #define NULL 0 unsigned int key; //用来输入/输出文件流类 unsigned int key2; //key和key2分别是用做了电话号码和姓名的关键字 int *p; struct node //新建节点(用户姓名、地址、电话号码、指向下一个结点的指针 ) { char name[8],address[20]; char num[11]; node * next; }; typedef node* pnode; typedef node* mingzi; //声明了名字和电话两个指针 node **phone; node **nam; node *a; void hash(char num[11]) //以电话号码为关键字建立哈希函数 { int i = 3; key=(int)num[2]; while(num[i]!=NULL) { key+=(int)num[i]; i++; } key=key%20; } void hash2(char name[8]) //姓名为关键字建立哈希函数 { int i = 1; key2=(int)name[0]; while(name[i]!=NULL) { key2+=(int)name[i]; i++; } key2=key2%20; } //强制类型转换,将用户名的每一个字母的ASCLL码值相加并且除以20后的余数 node* input() //输入节点信息 ,建立结点,并将结点的next指针指空 { node *temp; temp = new node; temp->next=NULL; cout<<"输入姓名:"<>temp->name; cout<<"输入地址:"<>temp->address; cout<<"输入电话:"<>temp->num; return temp; } //对于指针类型返回的是地址 int apend() //添加节点 { node *newphone; node *newname; newphone=input(); newname=newphone; newphone->next=NULL; newname->next=NULL; hash(newphone->num); //利用哈希函数计算出对应关键字的存储地址 hash2(newname->name); newphone->next = phone[key]->next; //利用电话号码为关键字插入 phone[key]->next=newphone; //是采用链地址法,拉链法处理冲突的散列表结构 newname->next = nam[key2]->next; //利用用户名为关键字插入 nam[key2]->next=newname; return 0; } void create() //新建节点 { int i; phone=new pnode[20]; //动态创建对象数组,C++课本P188页 for(i=0;inext=NULL; } } void create2() //新建节点 { int i; nam=new mingzi[20]; for(i=0;inext=NULL; } } void list() //显示列表 { int i; node *p; for(i=0;inext; while(p) { cout<name<<'_'<address<<'_'<num<next; } } } void list2() //显示列表 { int i; node *p; for(i=0;inext; while(p) { cout<name<<'_'<address<<'_'<num<next; } } } void find(char num[11]) //在以电话号码为关键字的哈希表查找用户信息 { hash(num); node *q=phone[key]->next; while(q!= NULL) { if(strcmp(num,q->num)==0) break; q=q->next; } if(q) cout<name<<"_" <address<<"_"<num<<endl; else cout<<"无此记录"<next; while(q!= NULL) { if(strcmp(name,q->name)==0) break; q=q->next; } if(q) cout<name<<"_" <address<<"_"<num<<endl; else cout<<"无此记录"<<endl; } void save() //保存用户信息 { int i; node *p; for(i=0;inext; while(p) { fstream iiout("out.txt", ios::out); //创建一个文件流对象:iiout iiout<name<<"_"<address<<"_"<num<next; } } } void menu() //菜单 { cout<<" 哈希表通讯录"<<endl; cout<<" 0.添加记录"<<endl; cout<<" 2.姓名散列"<<endl; cout<<" 3.查找记录"<<endl; cout<<" 4.号码散列"<<endl; cout<<" 5.清空记录"<<endl; cout<<" 6.保存记录"<<endl; cout<<" 7.退出系统"<>sel; if(sel==3) { cout<<"8姓名查询" <<endl;cout<<"9号码查询"<>b; if(b==9) {cout<<"请输入电话号码:"<>num; cout<<"输出查找的信息:"<<endl; find(num); } else {cout<<"请输入姓名:"<>name; cout<<"输出查找的信息:"<<endl; find2(name);}} if(sel==2) {cout<<"姓名散列结果:"<<endl; list2();} if(sel==0) {cout<<"请输入要添加的内容:"<<endl; apend();} if(sel==4) {cout<<"号码散列结果:"<<endl; list(); } if(sel==5) {cout<<"列表已清空:"<<endl; create();create2();} if(sel==6) { cout<<"通信录已保存:"<<endl; save();} if(sel==7) return 0; } return 0; }
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值