使用散列表进行电话号码查询系统的设计

#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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值