哈希查找(根据电话号查找)

直接上源码

具体解释在源码中,也要注意源码易出现的问题

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE 50

int Czy = 1;

typedef struct record 
{
	char Number[20];	// 电话 
	char Name[20];		// 姓名 
	char Address[20];	// 地址 
	int flag;	// 是否删除 
}Record;

typedef struct Hash
{
	Record *data;
	int cnt;
	int size;
}*HashTable,HashElem;

//定义及初始化 
HashElem table;
HashTable numbertable;
Record record[50];
 
//哈希函数,将电话号码每一位求和 
int GetHashKey(char ar[])
{
	int len = strlen(ar);
	int key = 0;
	int i;
	for(i = 0; i < len; i ++ )
	{
		key += ar[i] - '0';
	}
	return key % MAXSIZE;//必须取模,否则下标越界 
}

//冲突处理,二次探测再散列 
int HandleCollision(HashTable table, int key)
{
	Czy = 1; //从2,3,4,5,....... 
	while(1)
	{
		Czy ++ ; //从2,3,4,5,....... 
		if(Czy % 2 == 0) 
		{
			if(table->data[(key + (Czy / 2) * (Czy / 2)) % MAXSIZE].Name[0] == 0)
		 		return (key + (Czy / 2) * (Czy / 2)) % MAXSIZE;
		} 
		else if(Czy % 2 != 0) {
			if((key - (Czy / 2) * (Czy / 2)) < 0) continue;//由于是减法,要注意负数不能取模 
			if(table->data[(key - (Czy / 2) * (Czy / 2)) % MAXSIZE].Name[0] == 0)
		 		return (key - (Czy / 2) * (Czy / 2)) % MAXSIZE;
		}
	}
	//return -1;
}
 
//构建哈希表 
void CreateHashTable(HashTable table, Record *record, int n)
{
	int key;
	int i;
	for(i = 0; i < n; i ++ )
	{
		key = GetHashKey(record[i].Number);	// 得到key值 
		if(table->data[key].Name[0] != 0)	// 需要解决哈希冲突 
			key=HandleCollision(table, key);
		
		// 将结构体中的数据存储到哈希表中 
		strcpy(table->data[key].Number, record[i].Number);
		strcpy(table->data[key].Name, record[i].Name);
		strcpy(table->data[key].Address, record[i].Address);
	}	
}
 
//按照电话号码寻找 
int SerchKey(HashTable table, char PhoneNumber[])
{
	int flag = 0;
	int key = GetHashKey(PhoneNumber);
	if(strcmp(table->data[key].Number, PhoneNumber))	// 如果没有匹配成功,则对其尽心冲突查找 
	{
		for(Czy = 1; Czy < MAXSIZE; Czy ++ )
		{
			if(Czy % 2 == 0) 
			{
				if(!strcmp(PhoneNumber, table->data[(key + (Czy / 2) * (Czy / 2)) % MAXSIZE].Number))
				{
		 			key = (key + (Czy / 2) * (Czy / 2)) % MAXSIZE;
		 			break;
		 		}
			} 
			else if(Czy % 2 != 0) 
			{
				if((key - (Czy / 2) * (Czy / 2)) < 0) continue;//由于是减法,要注意负数不能取模 
				if(!strcmp(PhoneNumber, table->data[(key - (Czy / 2) * (Czy / 2)) % MAXSIZE].Number))
				{
		 			key = (key - (Czy / 2) * (Czy / 2)) % MAXSIZE;
					break;
		 		}
			}
		}
		flag = 1;
	} 
	if(flag) printf("未找到!请重新输入!\n");
	else 
	{
		if(!table->data[key].flag) printf("搜索到的号码信息为:\n%s %s %s\n",table->data[key].Name,table->data[key].Number,table->data[key].Address);
		else printf("未找到!请重新输入!\n");
	}
	return flag;
}

void add()
{
	int k = 0;
	int i;
	printf("请输入要添加的数量:\n");
	scanf("%d", &k);
	printf("请输入添加的信息(电话、姓名、地址):\n");
	for(i = 0; i < k; i ++ )
		scanf("%s %s %s", &record[i].Number, &record[i].Name, &record[i].Address);
	//创建哈希表 	
	CreateHashTable(numbertable, record, k); 
	printf("添加成功!\n");
}

void find()
{
	char PhoneNumber[20];
	printf("请输入要查找的电话:\n");
	scanf("%s", PhoneNumber);
	printf("给定的电话号码为:%s\n", PhoneNumber);
	SerchKey(numbertable, PhoneNumber); 
}

void revise(HashTable table)
{
	char PhoneNumber[20];
	char Name[20];
	char Address[20];
	int key;
	int flag = 0;
	printf("请输入要修改的电话:\n");
	scanf("%s", PhoneNumber);
	key = GetHashKey(PhoneNumber);
	if(strcmp(table->data[key].Number, PhoneNumber)){
		for(Czy = 1; Czy < MAXSIZE; Czy ++ ){
			if(Czy % 2 == 0) {
				if(!strcmp(PhoneNumber, table->data[(key + (Czy / 2) * (Czy / 2)) % MAXSIZE].Number)){
		 			key = (key + (Czy / 2) * (Czy / 2)) % MAXSIZE;
		 			break;
		 		}
			} 
			else if(Czy % 2 != 0) {
				if((key - (Czy / 2) * (Czy / 2)) < 0) continue;//由于是减法,要注意负数不能取模 
				if(!strcmp(PhoneNumber, table->data[(key - (Czy / 2) * (Czy / 2)) % MAXSIZE].Number)){
		 			key = (key - (Czy / 2) * (Czy / 2)) % MAXSIZE;
					break;
		 		}
			}
		}
		flag = 1;
	} 
	if(flag) printf("未找到!请重新输入!\n");
	else
	{
		if(!table->data[key].flag) 
		{
			printf("搜索到的号码信息为:\n%s %s %s\n", table->data[key].Name, table->data[key].Number, table->data[key].Address);
			printf("请输入你要修改的名字:\n");
			scanf("%s", &Name);
			printf("请输入你要修改的地址:\n"); 
			scanf("%s", &Address);
			strcpy(table->data[key].Name, Name);
			strcpy(table->data[key].Address, Address);
			printf("修改成功!\n"); 
		}
		else printf("未找到!请重新输入!\n"); 
	}
}
 
void del(HashTable table)
{
	char PhoneNumber[20];
	int key;
	int flag = 0;
	printf("请输入要删除的电话:\n");
	scanf("%s",PhoneNumber);
	key = GetHashKey(PhoneNumber);
	flag = SerchKey(numbertable,PhoneNumber); 
	if(!flag)
	{
		table->data[key].flag = 1;
		printf("删除成功!\n");
	}
}
 
int main(){
	int p = 0;
	int k = 0; 
	numbertable = &table;
	numbertable->data = (Record*)malloc(sizeof(record[0])*MAXSIZE);
	memset(numbertable->data, 0, sizeof(record[0])*MAXSIZE);
	numbertable->size = MAXSIZE;
	numbertable->cnt = 0;
	while(p != -1)
	{
		puts("");
		puts("");
		puts("");
		printf("\t\t电话号码查询系统\n");
		printf("\t\t1.添加电话\n");
		printf("\t\t2.查询电话\n");
		printf("\t\t3.修改信息\n");
		printf("\t\t4.删除电话\n");
		printf("\t\t5.退出系统\n");
		puts("");
		printf("\t\t请输入(1、2、3、4):\n"); 
		scanf("%d",&p);
		switch(p){
			case 1: add(); break;
			case 2: find(); break;
			case 3: revise(numbertable); break;
			case 4: del(numbertable); break;
			case 5: p = -1; break;
		}
	} 	
	return 0;
} 

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值