哈希表的设计与实现
c 语言 哈希表

C语言中的哈希表是一种数据结构,用于实现键-值对的存储和检索。
它通过将键映射到数组中的索引来实现高效的查找操作。
在C语言中,哈希表通常使用数组和链表的组合来实现。
一般情况下,哈希表包含一个固定大小的数组,每个数组元素称为一个桶(bucket)。
哈希函数将键映射到数组索引,每个键的哈希函数计算结果都应该是唯一的。
当需要插入一个键值对时,首先通过哈希函数计算键的哈希值,然后将键值对插入到对应索引的桶中。
如果多个键映射到相同的索引,这种情况称为哈希冲突。
为了解决冲突,每个桶通常是一个链表,新的键值对会被插入到链表的头部。
当需要查找一个键时,通过哈希函数计算键的哈希值,然后查找对应索引的桶。
在桶的链表中逐个比较键,直到找到对应的值或者链表结束。
需要注意的是,在哈希表中,哈希函数的设计非常重要,它应该尽可能均匀地将键分布到数组索引中,以减少哈希冲突的概率。
此外,当哈希表的负载因子过高时,即桶中键值对的数量过多,可能会导致性能下降,因此可能需要进行动态调整,例如重新分配更大的数组并重新插入所有键值对。
C语言中可以使用自定义的结构体来表示哈希表,包含数组和链表等成员变量。
操作哈希表的函数可以实现插入、查找、删除等操作,通过调用这些函数来使用哈希表。
总之,哈希表是一种在C语言中实现键-值对存储和检索的数据结构,通过哈希函数将键映射到数组索引,通过数组和链表的组合解决哈希冲突。
hashtable底层原理

hashtable底层原理Hashtable底层原理Hashtable是一种常见的数据结构,它可以快速地进行数据的查找和插入操作。
在Java中,Hashtable是一个非常常用的类,它的底层实现是基于哈希表的。
本文将从哈希表的基本原理、哈希函数的设计、哈希冲突的处理以及Hashtable的实现等方面来介绍Hashtable的底层原理。
一、哈希表的基本原理哈希表是一种基于数组的数据结构,它通过哈希函数将数据映射到数组的某个位置上。
哈希函数的设计是哈希表的关键,它决定了数据在数组中的位置。
哈希表的基本操作包括插入、查找和删除。
插入操作将数据插入到哈希表中,查找操作根据关键字查找数据,删除操作将数据从哈希表中删除。
二、哈希函数的设计哈希函数的设计是哈希表的关键,它决定了数据在数组中的位置。
哈希函数的设计需要满足以下几个条件:1. 映射范围:哈希函数需要将数据映射到数组的某个位置上,因此哈希函数的返回值需要在数组的范围内。
2. 均匀性:哈希函数需要将数据均匀地映射到数组的各个位置上,这样可以避免哈希冲突的发生。
3. 碰撞概率:哈希函数需要尽可能地减少哈希冲突的发生,这样可以提高哈希表的效率。
常见的哈希函数包括直接寻址法、除留余数法、数字分析法、平方取中法、折叠法等。
三、哈希冲突的处理哈希冲突是指不同的数据经过哈希函数映射到数组的同一个位置上。
哈希冲突的发生是不可避免的,因此需要采取一些方法来处理哈希冲突。
常见的哈希冲突处理方法包括开放地址法和链地址法。
开放地址法是指当哈希冲突发生时,继续寻找数组中的下一个空位置,直到找到为止。
链地址法是指将哈希冲突的数据存储在链表中,每个数组位置上存储一个链表头指针,指向链表的第一个节点。
四、Hashtable的实现Hashtable是Java中的一个非常常用的类,它的底层实现是基于哈希表的。
Hashtable的实现采用了链地址法来处理哈希冲突。
当哈希冲突发生时,将数据存储在链表中,每个数组位置上存储一个链表头指针,指向链表的第一个节点。
数据结构课程设计--哈希表实验报告

福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级:xxxxxx班座号:xxxxxxxxxxxx姓名:xxxxxxx2011年12 月31 日实验题目:哈希表一、要解决的问题针对同班同学信息设计一个通讯录,学生信息有姓名,学号,电话号码等。
以学生姓名为关键字设计哈希表,并完成相应的建表和查表程序。
基本要求:姓名以汉语拼音形式,待填入哈希表的人名约30个,自行设计哈希函数,用线性探测再散列法或链地址法处理冲突;在查找的过程中给出比较的次数。
完成按姓名查询的操作。
运行的环境:Microsoft Visual C++ 6.0二、算法基本思想描述设计一个哈希表(哈希表内的元素为自定义的结构体)用来存放待填入的30个人名,人名为中国姓名的汉语拼音形式,用除留余数法构造哈希函数,用线性探查法解决哈希冲突。
建立哈希表并且将其显示出来。
通过要查找的关键字用哈希函数计算出相应的地址来查找人名。
通过循环语句调用数组中保存的数据来显示哈希表。
三、设计1、数据结构的设计和说明(1)结构体的定义typedef struct //记录{NA name;NA xuehao;NA tel;}Record;录入信息结构体的定义,包含姓名,学号,电话号码。
typedef struct //哈希表{Record *elem[HASHSIZE]; //数据元素存储基址int count; //当前数据元素个数int size; //当前容量}HashTable;哈希表元素的定义,包含数据元素存储基址、数据元素个数、当前容量。
2、关键算法的设计(1)姓名的折叠处理long fold(NA s) //人名的折叠处理{char *p;long sum=0;NA ss;strcpy(ss,s); //复制字符串,不改变原字符串的大小写strupr(ss); //将字符串ss转换为大写形式p=ss;while(*p!='\0')sum+=*p++;printf("\nsum====================%d",sum);return sum;}(2)建立哈希表1、用除留余数法构建哈希函数2、用线性探测再散列法处理冲突int Hash1(NA str) //哈希函数{long n;int m;n=fold(str); //先将用户名进行折叠处理m=n%HASHSIZE; //折叠处理后的数,用除留余数法构造哈希函数return m; //并返回模值}Status collision(int p,int c) //冲突处理函数,采用二次探测再散列法解决冲突{int i,q;i=c/2+1;while(i<HASHSIZE){if(c%2==0){c++;q=(p+i*i)%HASHSIZE;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 UNSUCCESS;}void benGetTime();}else printf("\n此人不存在,查找不成功!\n");benGetTime();}(4)显示哈希表void ShowInformation(Record* a) //显示输入的用户信息{int i;system("cls");for( i=0;i<NUM_BER;i++)printf("\n第%d个用户信息:\n 姓名:%s\n 学号:%s\n 电话号码:%s\n",i+1,a[i].name,a[i].xuehao,a[i].tel);}(5)主函数的设计void main(int argc, char* argv[]){Record a[MAXSIZE];int c,flag=1,i=0;HashTable *H;H=(HashTable*)malloc(LEN);for(i=0;i<HASHSIZE;i++){H->elem[i]=NULL;H->size=HASHSIZE;H->count=0;}while (1){ int num;printf("\n ");printf("\n 欢迎使用同学通讯录录入查找系统");printf("\n 哈希表的设计与实现");printf("\n 【1】. 添加用户信息");printf("\n 【2】. 读取所有用户信息");printf("\n 【3】. 以姓名建立哈希表(再哈希法解决冲突) ");printf("\n 【4】. 以电话号码建立哈希表(再哈希法解决冲突) ");printf("\n 【5】. 查找并显示给定用户名的记录");printf("\n 【6】. 查找并显示给定电话号码的记录");printf("\n 【7】. 清屏");printf("\n 【8】. 保存");printf("\n 【9】. 退出程序");printf("\n 温馨提示:");printf("\n Ⅰ.进行5操作前请先输出3 ");printf("\n Ⅱ.进行6操作前请先输出4 ");printf("\n");printf("请输入一个任务选项>>>");printf("\n");scanf("%d",&num);switch(num){case 1:getin(a);break;case 2:ShowInformation(a);break;case 3:CreateHash1(H,a); /* 以姓名建立哈希表*/break;case 4:CreateHash2(H,a); /* 以电话号码建立哈希表*/break;case 5:c=0;SearchHash1(H,c);break;case 6:c=0;SearchHash2(H,c);break;case 7:Cls(a);break;case 8:Save();break;case 9:return 0;break;default:printf("你输错了,请重新输入!");printf("\n");}}system("pause");return 0;3、模块结构图及各模块的功能:四、源程序清单:#include<stdio.h>#include<stdlib.h>#include<string.h>#include <windows.h>#define MAXSIZE 20 #define MAX_SIZE 20 #define HASHSIZE 53 #define SUCCESS 1#define UNSUCCESS -1#define LEN sizeof(HashTable)typedef int Status;typedef char NA[MAX_SIZE];typedef struct {NA name;NA xuehao;NA tel;}Record;typedef struct {Record *elem[HASHSIZE]; int count; int size; }HashTable;Status eq(NA x,NA y) {if(strcmp(x,y)==0)return SUCCESS;else return UNSUCCESS;}Status NUM_BER;void getin(Record* a) {int i;system("cls");printf("输入要添加的个数:\n");scanf("%d",&NUM_BER);for(i=0;i<NUM_BER;i++){printf("请输入第%d个记录的姓名:\n",i+1);scanf("%s",a[i].name);printf("请输入%d个记录的学号:\n",i+1);scanf("%s",a[i].xuehao);printf("请输入第%d个记录的电话号码:\n",i+1);scanf("%s",a[i].tel);}}void ShowInformation(Record* a){int i;system("cls");for( i=0;i<NUM_BER;i++)printf("\n第%d个用户信息:\n 姓名:%s\n 学号:%s\n 电话号码:%s\n",i+1,a[i].name,a[i].xuehao,a[i].tel);}void Cls(Record* a){printf("*");system("cls");}long fold(NA s){char *p;long sum=0;NA ss;strcpy(ss,s);strupr(ss);p=ss;while(*p!='\0')sum+=*p++;printf("\nsum====================%d",sum);return sum;}int Hash1(NA str){int m;n=fold(str);m=n%HASHSIZE;return m;}int Hash2(NA str){long n;int m;n = atoi(str);m=n%HASHSIZE;return m;}Status collision(int p,int c){int i,q;i=c/2+1;while(i<HASHSIZE){if(c%2==0){c++;q=(p+i*i)%HASHSIZE;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 UNSUCCESS;}void benGetTime();void CreateHash1(HashTable* H,Record* a){ int i,p=-1,c,pp;system("cls"); benGetTime();for(i=0;i<NUM_BER;i++){p=Hash1(a[i].name);pp=p;while(H->elem[pp]!=NULL) {pp=collision(p,c);if(pp<0){printf("第%d记录无法解决冲突",i+1);continue;}}H->elem[pp]=&(a[i]);H->count++;printf("第%d个记录冲突次数为%d。
哈希实验报告

引言概述:本文旨在对哈希实验进行报告,重点介绍哈希实验的二次探测法、哈希函数、哈希表的查找、插入与删除操作,并分析实验结果。
通过本实验的开展,我们对哈希算法的原理、实现和性能有了更深入的理解,也增加了对数据结构的实践能力。
正文内容:一、二次探测法1.定义与原理2.步骤与流程3.优缺点分析4.实验过程与结果5.实验中的注意事项二、哈希函数1.哈希函数的设计原则2.常见的哈希函数算法3.哈希冲突与解决方法4.哈希函数的优化策略5.实验中的哈希函数选择与应用三、哈希表的查找操作1.哈希表的存储结构与基本操作2.直接定址法查找3.拉链法查找4.其他查找方法与比较5.实验结果与分析四、哈希表的插入与删除操作1.插入操作的实现思路2.插入操作的效率分析3.删除操作的实现思路4.删除操作的效率分析5.实验结果分析与对比五、实验结果与总结1.实验数据的统计与分析2.实验中的问题与解决方案3.实验结论与总结4.对哈希算法的进一步探讨与应用展望5.实验的意义与启示总结:通过对哈希实验的详细阐述,我们对二次探测法、哈希函数、哈希表的查找、插入与删除操作有了更深入的了解。
实验结果与分析表明,在哈希表的实现中,选择合适的哈希函数、解决哈希冲突以及优化插入与删除操作,对提高哈希表的性能至关重要。
哈希算法作为一种重要的数据结构应用,具有广泛的应用前景,在实际问题中具有重要的实践意义。
通过本次实验,我们不仅提升了对数据结构的理论理解,也增强了数据结构算法的实践能力,为今后的学习与研究打下了坚实的基础。
第七章-哈希表

哈希表又称散列表,实际上就是一个数组。
哈希函数是一个用来求存储在哈希的关键字在哈希表的地址下标的函数.比如一个哈希表int hashtable[5];现在有下面4个数要存入到哈希表中:(3,15,22,24)给定一个哈希函数: H(k)=k % 5最终数据存储如下图:理想情况下,哈希函数在关键字和地址之间建立了一个一一对应关系,从而使得查找只需一次计算即可完成。
由于关键字值的某种随机性,使得这种一一对应关系难以发现或构造。
因而可能会出现不同的关键字对应一个存储地址。
即k1≠k2,但H(k1)=H(k2),这种现象称为冲突。
把这种具有不同关键字值而具有相同哈希地址的对象称“同义词”。
在大多数情况下,冲突是不能完全避免的。
这是因为所有可能的关键字的集合可能比较大,而对应的地址数则可能比较少。
对于哈希技术,主要研究两个问题:(1)如何设计哈希函数以使冲突尽可能少地发生。
(2)发生冲突后如何解决。
哈希函数的构造方法:构造好的哈希函数的方法,应能使冲突尽可能地少,因而应具有较好的随机性。
这样可使一组关键字的散列地址均匀地分布在整个地址空间。
根据关键字的结构和分布的不同,可构造出许多不同的哈希函数。
1.直接定址法直接定址法是以关键字k本身或关键字加上某个数值常量c作为哈希地址的方法。
该哈希函数H(k)为:H(k)=k+c (c≥0)这种哈希函数计算简单,并且不可能有冲突发生。
当关键字的分布基本连续时,可使用直接定址法的哈希函数。
否则,若关键字分布不连续将造成内存单元的大量浪费。
2.除留余数法(注意:这种方法常用)取关键字k除以哈希表长度m所得余数作为哈希函数地址的方法。
即:H(k)=k %m这是一种较简单、也是较常见的构造方法。
这种方法的关键是选择好哈希表的长度m 。
使得数据集合中的每一个关键字通过该函数转化后映射到哈希表的任意地址上的概率相等。
理论研究表明,在m 取值为素数(质数)时,冲突可能性相对较少。
数据结构课程设计报告——哈希表实现电话号码查询

数据结构课程设计报告一、需求分析1问题描述:根据需要设计出合理的Hash函数,并由此建立相应的Hash表。
要求:1)每个电话用户信息包括(姓名,电话,住址)信息。
2)可以使用姓名与地址查找相应的用户信息。
3)使用Hash表实现。
使用开放定址法解决冲突。
2 基本要求:1)记录每个用户的姓名、地址和电话。
2)从键盘输入,以姓名和地址为关键字分别建立Hash表。
3)用开放地址法解决冲突。
4)分别按姓名和地址查找并显示电话号码。
二、概要设计三、详细设计typedef struct //定义结构Hash表{定义Hash表内的所有成员}HashTable[MaxSize];int Key(char x[])//关键字转换为数值{求字符数组x每个字符对应的asc值的绝对值之和,并返回最后结果}void CreateHT(HashTable ha)//创建Hash表{创建Hash表,并初始化它}void InsertHTna(HashTable ha,int &n,KeyType k,int d) //按姓名插入{以姓名为关键字,调用关键字转换函数将对应的电话号码存储到相应的存储空间。
若该位置已经被存储,则向后移一位(当移到最后一位,就移到头部继续)。
若还有冲突重复上一步。
当所有空间都查过一遍,发现没有空位,则输出“没有存储空间”。
}void InsertHTadd(HashTable ha,int &n,KeyType k,int d)//按地址插入{以地址为关键字,调用关键字转换函数将对应的电话号码存储到相应的存储空间。
若该位置已经被存储,则向后移一位(当移到最后一位,就移到头部继续)。
若还有冲突重复上一步。
当所有空间都查过一遍,发现没有空位,则输出“没有存储空间”。
}void InserHT(HashTable ha)//Hash表插入{输入用户姓名、地址和电话,分别调用按姓名插入和按地址插入函数进行插入。
c实现的hash表-概述说明以及解释

c实现的hash表-概述说明以及解释1.引言1.1 概述在计算机科学中,哈希表(Hash Table),又被称为散列表,是一种常用的数据结构。
它能够以常数时间复杂度(O(1))来实现插入、删除和查找等操作,因此具有高效的特性。
哈希表通过哈希函数将键(key)映射到一个固定大小的数组(通常称为哈希表)。
通过这种映射关系,我们可以在数组中快速访问到对应的值(value)。
常见的应用场景包括缓存系统、数据库索引、编译器符号表等。
相对于其他数据结构,哈希表具有以下优点:1. 高效的插入、删除和查找操作:哈希表在插入、删除和查找数据时以常数时间复杂度进行操作,无论数据量大小,都能快速地完成操作。
2. 高效的存储和检索:通过哈希函数的映射关系,哈希表能够将键值对存储在数组中,可以通过键快速地找到对应的值。
3. 空间效率高:哈希表通过哈希函数将键映射到数组下标,能够充分利用存储空间,避免冗余的存储。
然而,哈希表也存在一些局限性:1. 冲突问题:由于哈希函数的映射关系是将多个键映射到同一个数组下标上,可能会导致冲突。
解决冲突问题的常见方法包括链地址法(Chaining)和开放定址法(Open Addressing)等。
2. 内存消耗:由于哈希表需要维护额外的空间来存储映射关系,所以相比于其他数据结构来说,可能会占用较多的内存。
本篇长文将重点介绍C语言实现哈希表的方法。
我们将首先讨论哈希表的定义和实现原理,然后详细介绍在C语言中如何实现一个高效的哈希表。
最后,我们将总结哈希表的优势,对比其他数据结构,并展望哈希表在未来的发展前景。
通过本文的学习,读者将能够深入理解哈希表的底层实现原理,并学会如何在C语言中利用哈希表解决实际问题。
1.2 文章结构本文将围绕C语言实现的hash表展开讨论,并按照以下结构进行组织。
引言部分将对hash表进行概述,介绍hash表的基本概念、作用以及其在实际应用中的重要性。
同时,引言部分还会阐述本文的目的,即通过C语言实现的hash表,来探讨其实现原理、方法以及与其他数据结构的对比。
JS模拟实现哈希表及应用详解

JS模拟实现哈希表及应⽤详解本⽂实例讲述了JS模拟实现哈希表及应⽤。
分享给⼤家供⼤家参考,具体如下:在算法中,尤其是有关数组的算法中,哈希表的使⽤可以很好的解决问题,所以这篇⽂章会记录⼀些有关js实现哈希表并给出解决实际问题的例⼦。
说明:这篇⽂章所写并不是真正意义的哈希表,只是与哈希表的使⽤有相似之处。
第⼀部分:相关知识点属性的枚举:var person = {name: "zzw",sex: "Male",age: 21};for (var prop in person) {console.log(prop + " ",person[prop]);}输出:即对于对象⽽⾔,我们可以使⽤for in来枚举对象的属性。
属性的删除:var person = {name: "zzw",sex: "Male",age: 21};var ifRemove = delete ;for (var prop in person) {console.log(prop + " ",person[prop]);}console.log(ifRemove);对象的属性可以通过 delete 来删除,并且会有⼀个返回值。
如下:注意:⼀般只有对象的属性才可以删除,⽽变量是不能删除的,如:var x = 1;console.log(delete x);这时打印台输出false,因为变量是不可被删除的。
检测属性是否存在:var person = {name: "zzw",sex: "Male",age: 21};console.log("age" in person);console.log("someOther" in person);前者返回true,后者返回false。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
洛阳理工学院课程设计报告课程名称数据结构课程设计设计题目哈希表的设计与实现专课程设计任务书设计题目:哈希表的设计与实现_________________________________ _________________________________________________________ 设计内容与要求:内容:1、设每个记录有下列数据项:电话号码、用户名、地址;2、从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;3、采用再哈希法解决冲突;4、查找并显示给定电话号码的记录;5、查找并显示给定用户名的记录。
6、在哈希函数确定的前提下,尝试各种不同类型处理冲突的方法(至少两种),考察平均查找长度的变化。
课程设计评语成绩:指导教师:_______________年月日目录一.问题描述 (2)二.基本要求 (2)三.数据结构 (2)四.总体设计 (2)五.详细设计 (3)5.1录入功能 void lurugongneng() (3)5.2查询功能 void chaxungongnen() (3)5.3订票功能 void dingpiaogongnen() (4)5.4退票功能 void tuipiaogongnen() (4)5.5修改功能 void xiugaigongnen()................ 错误!未定义书签。
六.测试与调试. (4)6.1 程序的模块 (4)6.2 程序的调试 (4)6.3 测试结果 (5)七.源程序清单 (6)一.问题描述通过此系统可以实现如下功能:录入:可以录入通讯录情况查询:查询通讯录内的所有人插入:在通讯录内插入后来自己想要的人的信息删除:删除自己需要删除的信息修改:修改通讯录内的个人信息二.基本要求根据以上功能说明,设计哈希表通讯录的存储结构,设计程序完成功能。
三.数据结构int key; // 定义两个关键字为全局变量int key2;int *p;struct node{//建立节点,每个节点包括用户姓名,地址电话号码,以及指向下一个节点的指针 char name[8],address[20];char num[11];node *next;};四.总体设计五.详细设计5.1录入功能 void add()通过调用hash()和hasg2()函数录入个人信息,输入的航线信息包括姓名,地址,电话号码。
5 .2查询功能 void display()查询分为按目的地查询和按航班号查询,通过void display()函数调用search_name()//通过姓名查询函数和void search_num()//通过电话查询函数。
通过n控制功能选择,若找到,则输出该信息,否则提示用户没找到,退出。
5.3添加功能 void add()调用add()函数用来将需要插入的信息,插入到哈希表中,调用hash()函数将信息进行哈希排序。
并存储起来。
5.4删除功能 void create()调用create()函数,重新建议一个哈希表,覆盖掉以前的哈希表,就删除了以前建立的哈希表。
六.测试与调试6.1 程序的模块录入功能:原始数据的输入。
查询功能:根据客户需要,查询相关信息。
删除功能:根据客户的不同情况,删除信息。
退出功能:退出系统。
6.2 程序的调试(1)程序在起初的时候,在建立数据结构的时候有了一些困难,在查询了书之后,我建立了数据结构函数定义的数据类型出现了问题,对函数的定义不清楚,字符的不正确定义造成了后期大量的纠错工作(2)在写程序的时候忘记了一些c语言的语言规范,导致程序中出现了许多低级的错误(3)测试用例具有一定的广泛性。
运行程序时输入了多种不同字符信息,经过多次修改结果达到了预期效果,说明程序具有一定的可靠性和稳定性。
6.3 测试结果图 6-1 录入功能图 6-2 通过姓名查询图 6-3 通过电话查询图 6-5 删除功能七.源程序清单#include<string.h>#include<stdio.h>#include<stdlib.h>int key; // 定义两个关键字为全局变量int key2;int *p;struct node{//建立节点,每个节点包括用户姓名,地址电话号码,以及指向下一个节点的指针 char name[8];char address[20];char num[11];node *next;};typedef node* pnode;typedef node* mingzi;node **phone;//二级指针node **nam;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]){//哈希函数以用户名为关键字建立哈希表//利用强制类型转换,将用户名的每一个字母的asc2码值相加并除以后的余数int i =1;key2 = (int)name[0];while(name[i] != NULL){key2+=(int)name[i];i++;}key2=key2%20;}node *input(){//输入节点信息,建立节点,并将节点的next指空node* temp;temp = new node;temp->next = NULL;printf("请输入姓名\n");scanf("%s",temp->name);printf("请输入地址");scanf("%s",temp->address);printf("请输入电话");scanf("%s",temp->num);return temp; // 返回指针类型}int add(){//添加节点node *newphone;node *newname;newphone=input();newname=newphone;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(){//新建节点phone= new pnode[20];for(int i= 0;i<20;i++){phone[i]=new node;phone[i]->next=NULL;}}void create2(){int i;nam = new mingzi[20];for(i=0;i<20;i++){nam[i]=new node;nam[i]->next=NULL;}}void display(){int i;node *p=NULL;for(int i=0;i<20;i++){p=nam[i]->next;while(p){printf("%s_%s_%s\n",p->name,p->address,p->num); p=p->next;}}}void search_num(char num[]){//在以电话号码为关键字的哈希表中查找用户信息hash(num);node *q=phone[key]->next;while(q != NULL){if(strcmp(num,q->num) == 0)break;q = q->next;}if(q)printf("%s_%s_%s\n",q->name,q->address,q->num);elseprintf("无此记录\n ");}void search_name(char name[8]){//以用户名为关键字在哈希表中查找用户hash2(name);node *q=nam[key2]->next;while(q!=NULL){if(strcmp(name,q->name)==0)break;q=q->next;}if(q){printf("%s_%s_%s\n",q->name,q->address,q->num);}elseprintf("无此记录\n");}void menu(){//菜单printf("----------------------------------------------\n"); printf("---------------------------菜单如下,请输入选择----------------\n");printf("---0添加记录\n");printf("---1查询记录\n");printf("---2显示记录\n");printf("---3清空记录\n");printf("---4退出系统\n");}int main(){char num[11]; //定义类型char name[8];create(); //开始创建函数create2();int sel ;while(1){menu();scanf("%d",&sel); //输入选择switch(sel){case 1:{system("cls");printf("6号码查询,姓名查询\n");int b;scanf("%d",&b);if(b==6){//按照号码查询printf("请输入电话号码");scanf("%s",num);printf("输出查找的信息");search_num(num);}else{printf("请输入姓名\n");scanf("%s",name);printf("输出查找的信息\n"); search_name(name);}}break;case 2:{//显示记录的所有信息system("cls");printf("显示结果\n");display();} break;case 0:{//添加记录system("cls");printf("请输入要添加的内容");add();}break;case 3:{system("cls");printf("列表已经清空");create();//重新创建函数create2();}break;default :return 0; //否则退出}}return 0;}。