基于c语言的哈希表电话簿

一、需求分析 1
二、概要设计 2
三、详细设计 3-8
四、调试分析 9-11
五、运行结果 12-21
六、参考文献 21
七、附录 21-47

一、需求分析
1.设计目的
电话簿是人们用来记录亲人朋友电话的工具,发展至现在已经不只是传统的纸制本子,电脑,手机等电子产品也都具备了记录的功能。电话簿作为手机的基本功能之一,每天都被我们频繁地使用着,根据手机功能使用调查显示,有八成以上的消费者使用手机电话簿功能。
本次设计的电话簿是一款绝对专业的个人通讯信息管理软件,本次设计的电话簿就是为了方便消费者以不同的方式查找和储存电话。电话簿中储存方式大致可分为两类,一类是按照姓名来储存入电话簿,另一种是按照电话号码来储存入电话簿。为了更贴近用户需求,本次设计的电话簿包含了以上两种储存和查找方式。

2.程序所能达到的功能
(1)用户可以通过键盘输入来选择以号码或者名字为关键字建表。
(2)从键盘输入要插入的的记录,分别以线性探测法和二次探测法来解决冲突。
(3)用户通过输入电话号码查找,可以给出电话号码的记录。
(4)用户通过输入用户名查找,可以给出电话号码的记录。
(5)在哈希函数确定的前提下,分别以线性探测法和二次探测法来解决冲突,并计算平均查找长度。
(6)展示表中所有的电话记录。

二、概要设计
本系统旨在通过建立哈希表实现电话簿录入、查询电话记录、展示所有电话记录等功能,帮助用户方便的处理电话记录。
简单思路:
在这里插入图片描述

建立表:
对于通过电话号码和地址为关键字建立哈希表,使用除留余数法。
解决冲突:
分别使用二次探测法和线性探测法来解决冲突。

三、详细设计
3.1建立哈希表(实例)的存储结构
将每个人的信息作为一条记录,包括电话号码、用户名、地址,还有一个整型变量用来记录冲突的次数,便于计算ASL,然后哈希表由记录数组、表中现存量、表容量组成,具体数据类型见下:
address[20] 地址
name[30]; 名字
num[30] 电话号码
int c; 查找次数
结构体 {

char name[30];名字

char address[20];地址
char num[30];电话号码
int c;查找次数

}record;

结构体{
record data[Size];哈希表
int count;现在有的数据个数
int size;哈希表长度

} Hashtable;

在这里插入图片描述

3.2建立哈希表(实例)的操作
为了实现上述程序的功能,需要定义下列抽象数据类型:
ADT hashtable {
数据对象:哈希表中存储的个条电话记录;
数据关系:表中相邻元素之间有前去和后继的关系;
基本操作:
init(Hashtable &h)
操作结果:初始化了哈希表
int exchange(char str[])
操作结果:请关键字从char型转为int;
int HashSearch1(Hashtable &h,char *str,int &p)
操作结果:在表中以电话号码线性探测数据,返回数据插入位置;
int HashSearch1_n(Hashtable &h,char *str,int &p)
操作结果:在表中以姓名线性探测数据,返回数据的插入位置;
int HashSearch2(Hashtable &h,char *str,int &p)
操作结果:在表中以电话号码二次探测数据,返回数据的插入位置;
int HashSearch2(Hashtable &h,char *str,int &p)
操作结果:在表中以姓名二次探测数据,返回数据的插入位置;
void disp(Hashtable h)
操作结果:显示出哈希表中储存的电话记录;
}ADT hashtable

3.3程序具体实行流程
(1)主菜单和次菜单的进入和退出。
利用while(1){}和swith语句来实现主菜单和次菜单的转换

while(1)语句可以让程序一直运行,每结束一次操作后重新再来;
swith(主菜单)语句在主菜单选择建立哈希表的关键字;
swith(次菜单)语句在次菜单选择电话簿功能;
cc=menu_1();重新选择swith(主菜单);

在这里插入图片描述

(2)建立哈希函数——采取除留余数法
第一步:把字符串先转化为一个整数。
int exchange(char str[]) 使用关键字的哈希函数,各项转化为整数型相加;

第二步:与哈希表的最大容量使用除留余数法得到哈希函数。
j=k%Size;

在这里插入图片描述

(3)解决冲突——线性探测法和二次探测法

线性探测法:
在这里插入图片描述

二次探测法:

在这里插入图片描述

(4)计算ASL

在这里插入图片描述

int c;查找次数
int count;现在有的数据个数
结构体中定义了c来计录每一个记录的比较次数,方便最后求ASL。
ASL=

(5)展示电话簿
循环使用for循环查找整个哈希表
在这里插入图片描述

四、调试分析
》》》》》》

主程序

void main()
{
   
 Hashtable h1,h2,h3,h4;
 int i,j,cc,n,a,m,flag=1,k=5;
 char num[30];
 char name[30];
 char address[20];
 init(h1);
 init(h2);
 init(h3);
 init(h4);
	cc=menu_1();
	while(1){
   
	switch(cc){
   
	case 1:
		system("cls");
		 j=menu_2();
		 switch(j){
   
		 case 0:
			 printf("(@ @) 谢谢使用,再见! (^ ^)\n");
			 exit(0);
			 getch();
		 break;
		 //******
		 case 1:
		//重新选择关键字
		   cc=menu_1();
			  break;
		 //******
		 case 2:
			 printf("添加电话记录到电话簿1:\n");
			 printf("请输入您要添加电话记录的数目:\n");
			 scanf("%d",&n);
			 for(i=0;i<n;i++){
   
				 printf("请输入第%d条电话记录的姓名、地址和电话号码(用空格隔开)\n"
  • 17
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
是一种常用的数据结构,可以用来快速查找数据。在电话簿这个场景中,可以使用哈来实现电话簿的存储和查找。在C语言中,可以通过定义结构体和使用指针来实现哈。 具体实现方式如下: 1. 定义一个结构体,包含电话号码和姓名等信息。 2. 定义一个哈结构体,包含哈的大小、每个桶的大小、每个桶的指针等信息。 3. 实现哈函数,将电话号码转换成桶的索引。 4. 实现插入函数,将电话号码和姓名插入到哈中对应的桶中。 5. 实现查找函数,根据电话号码在哈中对应的桶中查找对应的姓名。 下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 1000 // 哈最大大小 #define BUCKET_SIZE 10 // 每个桶最大大小 // 电话簿结构体 typedef struct { char name[20]; // 姓名 char phone[20]; // 电话号码 } PhoneBook; // 哈桶结构体 typedef struct { int size; // 当前桶大小 PhoneBook *data[BUCKET_SIZE]; // 桶数据 } Bucket; // 哈结构体 typedef struct { int size; // 哈大小 Bucket *buckets[MAX_SIZE]; // 哈桶数组 } HashTable; // 哈函数,将电话号码转换成桶的索引 int hash(char *phone, int size) { int sum = 0; for (int i = 0; i < strlen(phone); i++) { sum += phone[i]; } return sum % size; } // 初始化哈 void initHashTable(HashTable *hashTable, int size) { hashTable->size = size; for (int i = 0; i < size; i++) { Bucket *bucket = (Bucket *)malloc(sizeof(Bucket)); bucket->size = 0; for (int j = 0; j < BUCKET_SIZE; j++) { bucket->data[j] = NULL; } hashTable->buckets[i] = bucket; } } // 插入函数,将电话号码和姓名插入到哈中对应的桶中 void insert(HashTable *hashTable, char *name, char *phone) { int index = hash(phone, hashTable->size); Bucket *bucket = hashTable->buckets[index]; PhoneBook *phoneBook = (PhoneBook *)malloc(sizeof(PhoneBook)); strcpy(phoneBook->name, name); strcpy(phoneBook->phone, phone); if (bucket->size < BUCKET_SIZE) { bucket->data[bucket->size] = phoneBook; bucket->size++; } } // 查找函数,根据电话号码在哈中对应的桶中查找对应的姓名 char *find(HashTable *hashTable, char *phone) { int index = hash(phone, hashTable->size); Bucket *bucket = hashTable->buckets[index]; for (int i = 0; i < bucket->size; i++) { if (strcmp(bucket->data[i]->phone, phone) == 0) { return bucket->data[i]->name; } } return NULL; } // 测试代码 int main() { HashTable hashTable; initHashTable(&hashTable, MAX_SIZE); insert(&hashTable, "张三", "123456"); insert(&hashTable, "李四", "234567"); insert(&hashTable, "王五", "345678"); char *name = find(&hashTable, "234567"); if (name != NULL) { printf("姓名:%s\n", name); } else { printf("未找到该电话号码\n"); } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海大干饭人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值