哈希表的设计与实现

合集下载

c 语言 哈希表

c 语言 哈希表

C语言中的哈希表是一种数据结构,用于实现键-值对的存储和检索。

它通过将键映射到数组中的索引来实现高效的查找操作。

在C语言中,哈希表通常使用数组和链表的组合来实现。

一般情况下,哈希表包含一个固定大小的数组,每个数组元素称为一个桶(bucket)。

哈希函数将键映射到数组索引,每个键的哈希函数计算结果都应该是唯一的。

当需要插入一个键值对时,首先通过哈希函数计算键的哈希值,然后将键值对插入到对应索引的桶中。

如果多个键映射到相同的索引,这种情况称为哈希冲突。

为了解决冲突,每个桶通常是一个链表,新的键值对会被插入到链表的头部。

当需要查找一个键时,通过哈希函数计算键的哈希值,然后查找对应索引的桶。

在桶的链表中逐个比较键,直到找到对应的值或者链表结束。

需要注意的是,在哈希表中,哈希函数的设计非常重要,它应该尽可能均匀地将键分布到数组索引中,以减少哈希冲突的概率。

此外,当哈希表的负载因子过高时,即桶中键值对的数量过多,可能会导致性能下降,因此可能需要进行动态调整,例如重新分配更大的数组并重新插入所有键值对。

C语言中可以使用自定义的结构体来表示哈希表,包含数组和链表等成员变量。

操作哈希表的函数可以实现插入、查找、删除等操作,通过调用这些函数来使用哈希表。

总之,哈希表是一种在C语言中实现键-值对存储和检索的数据结构,通过哈希函数将键映射到数组索引,通过数组和链表的组合解决哈希冲突。

哈希表 哈希函数

哈希表 哈希函数

哈希表哈希函数哈希表是一种常见的数据结构,它通过哈希函数将键映射到存储位置,实现高效的数据查找和插入操作。

本文将从哈希函数的定义、设计原则、应用场景等方面进行介绍和探讨。

一、哈希函数的定义哈希函数是将任意长度的输入映射为固定长度输出的函数。

它的设计目标是将输入的数据分散到哈希表的不同槽位中,尽量避免冲突,使得数据能够均匀地分布在哈希表中。

二、哈希函数的设计原则1. 均匀性:好的哈希函数应该将输入的数据均匀地映射到哈希表的不同槽位中,避免冲突的发生。

常用的哈希函数有除留余数法、平方取中法等。

2. 确定性:同一个输入应该得到相同的输出,这样才能实现数据的查找和插入操作。

3. 高效性:哈希函数的计算速度应该尽可能快,以提高整体的性能。

三、哈希函数的应用场景1. 字典存储:哈希表可以用于实现字典存储结构,将键值对按照键的哈希值存储在哈希表中。

这样可以通过键快速地查找对应的值。

2. 缓存管理:哈希表可以用于实现缓存管理,将数据的哈希值作为索引,将数据存储在哈希表中。

这样可以加快数据的读取速度。

3. 唯一标识:哈希函数可以将数据转化为唯一的标识,用于数据的比较和去重。

例如,在分布式系统中,可以使用哈希函数将数据分配到不同的节点上。

四、哈希函数的性能评估1. 冲突率:冲突率是指哈希函数产生冲突的概率。

冲突率越低,哈希表的性能越好。

2. 均匀性:好的哈希函数应该将数据均匀地映射到哈希表的不同槽位中,避免槽位的过度拥挤。

3. 计算速度:哈希函数的计算速度应该尽可能快,以提高整体的性能。

五、哈希函数的优化策略1. 良好的分布性:选择合适的哈希函数,使得输入数据在哈希表中均匀分布,避免冲突的发生。

2. 良好的计算性能:选择计算速度较快的哈希函数,减少计算的时间消耗。

3. 避免冲突:可以通过增加哈希表的大小或者使用链表等方法来解决冲突的问题。

六、哈希函数的局限性1. 冲突:由于哈希函数的输出是有限的,而输入的数据是无限的,所以冲突是无法完全避免的。

hash的实现方式

hash的实现方式

hash的实现方式一、哈希的概念和作用哈希(Hash)是一种将任意长度的输入通过散列算法转换成固定长度输出的过程。

哈希算法的设计目标是将数据映射到尽可能唯一的哈希值,以便用于快速的数据存储和检索。

哈希的实现方式有很多种,下面将介绍几种常见的实现方式及其应用。

二、消息摘要算法消息摘要算法是哈希算法的一种常见实现方式,它将任意长度的数据转换为固定长度的摘要,也称为哈希值。

常见的消息摘要算法有MD5、SHA-1和SHA-256等。

这些算法具有以下特点:1. 输入数据的长度可以是任意的,输出的哈希值长度固定。

2. 相同的输入数据会产生相同的哈希值。

3. 即使输入数据只有微小的改变,也会产生完全不同的哈希值。

4. 很难通过哈希值反推出原始输入数据。

消息摘要算法广泛应用于数据完整性校验、数字签名、密码存储等场景。

三、密码哈希函数密码哈希函数是一种特殊的哈希函数,它在保证哈希性质的同时,加入了一些特殊的设计,以增加密码的安全性。

常见的密码哈希函数有bcrypt和scrypt等。

这些函数具有以下特点:1. 输入数据的长度可以是任意的,输出的哈希值长度固定。

2. 相同的输入数据会产生相同的哈希值。

3. 为了增加安全性,这些函数会加入盐(salt)和迭代次数的概念。

4. 盐是一个随机生成的字符串,用于增加哈希值的复杂度。

5. 迭代次数表示对哈希算法的多次迭代,以增加计算时间,提高破解难度。

密码哈希函数广泛应用于用户密码的存储和验证,以及安全敏感数据的保护。

四、哈希表哈希表是一种将键(Key)映射到值(Value)的数据结构,它通过哈希函数将键转换为索引,然后将值存储在对应的索引位置。

哈希表的实现方式有很多种,其中最常见的是使用数组和链表的组合。

哈希表具有以下特点:1. 通过哈希函数将键转换为索引,实现快速的插入、查找和删除操作。

2. 哈希函数应尽可能将键均匀地映射到索引,以避免冲突。

3. 冲突是指不同的键经过哈希函数计算后得到相同的索引,可以通过链表解决。

hashtable底层原理

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 Table)也叫散列表,是根据关键码值(Key Value)⽽直接进⾏访问的数据结构。

它通过把关键码值映射到哈希表中的⼀个位置来访问记录,以加快查找的速度。

这个映射函数就做散列函数,存放记录的数组叫做散列表。

2、散列存储的基本思路以数据中每个元素的关键字K为⾃变量,通过散列函数H(k)计算出函数值,以该函数值作为⼀块连续存储空间的的单元地址,将该元素存储到函数值对应的单元中。

3、哈希表查找的时间复杂度哈希表存储的是键值对,其查找的时间复杂度与元素数量多少⽆关,哈希表在查找元素时是通过计算哈希码值来定位元素的位置从⽽直接访问元素的,因此,哈希表查找的时间复杂度为O(1)。

⼆、常⽤的哈希函数1. 直接寻址法取关键字或者关键字的某个线性函数值作为哈希地址,即H(Key)=Key或者H(Key)=a*Key+b(a,b为整数),这种散列函数也叫做⾃⾝函数.如果H(Key)的哈希地址上已经有值了,那么就往下⼀个位置找,知道找到H(Key)的位置没有值了就把元素放进去.2. 数字分析法分析⼀组数据,⽐如⼀组员⼯的出⽣年⽉,这时我们发现出⽣年⽉的前⼏位数字⼀般都相同,因此,出现冲突的概率就会很⼤,但是我们发现年⽉⽇的后⼏位表⽰⽉份和具体⽇期的数字差别很⼤,如果利⽤后⾯的⼏位数字来构造散列地址,则冲突的⼏率则会明显降低.因此数字分析法就是找出数字的规律,尽可能利⽤这些数据来构造冲突⼏率较低的散列地址.3. 平⽅取中法取关键字平⽅后的中间⼏位作为散列地址.⼀个数的平⽅值的中间⼏位和数的每⼀位都有关。

因此,有平⽅取中法得到的哈希地址同关键字的每⼀位都有关,是的哈希地址具有较好的分散性。

该⽅法适⽤于关键字中的每⼀位取值都不够分散或者较分散的位数⼩于哈希地址所需要的位数的情况。

4. 折叠法折叠法即将关键字分割成位数相同的⼏部分,最后⼀部分位数可以不同,然后取这⼏部分的叠加和(注意:叠加和时去除进位)作为散列地址.数位叠加可以有移位叠加和间界叠加两种⽅法.移位叠加是将分割后的每⼀部分的最低位对齐,然后相加;间界叠加是从⼀端向另⼀端沿分割界来回折叠,然后对齐相加.5. 随机数法选择⼀个随机数,去关键字的随机值作为散列地址,通常⽤于关键字长度不同的场合.6. 除留余数法取关键字被某个不⼤于散列表表长m的数p除后所得的余数为散列地址.即H(Key)=Key MOD p,p<=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表-概述说明以及解释

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表,来探讨其实现原理、方法以及与其他数据结构的对比。

哈希表的设计与实现

哈希表的设计与实现

合肥学院计算机科学与技术系课程设计报告2007~2008学年第2学期课程数据结构与算法课程设计名称哈希表的设计与实现学生姓名学号0604011026专业班级06 计科 (1)指导教师2008年9月一、课程设计题目:(哈希表的设计与实现的问题)设计哈希表实现电话号码查询系统。

设计程序完成以下要求:( 1)设每个记录有下列数据项:电话号码、用户名、地址;(2)从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;( 3)采用再哈希法解决冲突;(4)查找并显示给定电话号码的记录;(5)查找并显示给定用户的记录。

二、问题分析和任务定义1、问题分析要完成如下要求:设计哈希表实现电话号码查询系统。

实现本程序需要解决以下几个问题:(1)如何设计一个结点使该结点包括电话号码、用户名、地址。

(2)如何分别以电话号码和用户名为关键字建立哈希表。

(3)如何利用再哈希法解决冲突。

(4)如何实现用哈希法查找并显示给定电话号码的记录。

(5)如何查找并显示给定用户的记录。

2、任务定义由问题分析知,本设计主要要求分别以电话号码和用户名为关键字建立哈希表,并实现查找功能。

所以本设计的核心问题是如何解决散列的问题,亦即设计一个良好的哈希表。

由于结点的个数无法确认,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题。

所以采用链地址法散列算法。

采用链地址法,当出现同义词冲突时,使用链表结构把同义词链接在一起,即同义词的存储地址不是散列表中其他的空地址。

首先,解决的是定义链表结点,在链地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成.name[8]、num[11]和address[20]都是char浮点型,输入输出都只能是浮点型的。

采用链地址法,其中的所有同义词构成一个单链表,再由一个表头结点指向这个单链表的第一个结点。

这些表头结点组成一个一维数组,即哈希表。

哈希表的c语言实现

哈希表的c语言实现

下面是一个简单的C语言实现哈希表的代码示例:#include <stdio.h>#include <stdlib.h>#include <string.h>#define TABLE_SIZE 100#define DEFAULT_LOAD 0.7typedef struct {char *key;int value;} Element;typedef struct {Element *table[TABLE_SIZE];int count;double load;} HashTable;void createHashTable(HashTable *ht, int size) {for (int i = 0; i < size; ++i) {ht->table[i] = NULL;}ht->count = 0;ht->load = DEFAULT_LOAD;}void destroyHashTable(HashTable *ht) {for (int i = 0; i < ht->count; ++i) {Element *elem = ht->table[i];while (elem != NULL) {Element *tmp = elem;elem = elem->next;free(tmp);}}ht->count = 0;}Element *hash(HashTable *ht, char *key) {int index = (int)(strlen(key) * ht->load + rand() % ht->count);return ht->table[index] == NULL ? NULL : ht->table[index]->table[index & 0x7f]; }void insert(HashTable *ht, char *key, int value) { Element *elem = hash(ht, key);if (elem == NULL) {elem = (Element *)malloc(sizeof(Element));elem->key = strdup(key);elem->value = value;ht->table[0][0] = elem;ht->count++;if (ht->count > ht->load * ht->count) {double load = ht->load;int i = 0;while (true) {if (ht->table[i] == NULL) {break;}elem = ht->table[i]->table[0];free(ht->table[i]->table[0]);ht->table[i]->table[0] = elem;ht->count--;if (ht->count < load * ht->count) {break;}ht->table[++i] = NULL;}}} else {Element *p = elem;while (p->next != NULL) {p = p->next;}p->next = (Element *)malloc(sizeof(Element));p->next->key = strdup(key);p->next->value = value;}ht->count++;}void remove(HashTable *ht, char *key) {Element *p = ht->table[0];while (p != NULL) {if (strcmp(p->key, key) == 0) {Element *q = p->next;free(p);ht->table[0] = q;ht->count--;return;}p = p->next;}}int main() {HashTable ht = {.table = {0}, .count = 0, .load = DEFAULT_LOAD};createHashTable(&ht, TABLE_SIZE);insert(&ht, "key1", 1);insert(&ht, "key2", 2);insert(&ht, "key3", 3);remove(&ht, "key2");printf("Count: %d\n", ht.count);printf("Value: %d\n", ht.table[0]->value);destroyHashTable(&ht);return 0;}在这个示例中,我们定义了一个哈希表结构体HashTable,其中包含一个元素数组table和一个计数器count,以及一个用于存储当前负载的变量load。

c语言hashmap 查找方法

c语言hashmap 查找方法

c语言hashmap 查找方法
在C语言中,实现哈希表(hashmap)的查找方法通常需要经历
以下步骤:
1. 哈希函数设计,首先,你需要设计一个哈希函数,它能够将
输入的键(key)映射到哈希表中的一个位置。

一个好的哈希函数应
该能够尽可能地均匀地将键映射到不同的位置,以减少冲突的发生。

2. 冲突处理,由于哈希函数的映射可能会导致不同的键映射到
同一个位置,因此需要一种方法来处理这种冲突。

常见的冲突处理
方法包括链地址法和开放寻址法。

在C语言中,你需要根据具体情
况选择合适的冲突处理方法,并实现相应的逻辑。

3. 查找操作:一旦哈希表中的数据经过哈希函数映射并存储起来,你就可以通过键来查找对应的数值。

在C语言中,通常可以通
过以下步骤来实现查找操作:
使用哈希函数计算键对应的哈希值。

根据哈希值找到对应的存储位置。

如果使用链地址法,需要遍历对应位置的链表来查找键;如果使用开放寻址法,需要根据特定的规则来寻找下一个位置,直到找到对应的键或者确定该键不存在。

4. 错误处理,在实现查找方法时,需要考虑键可能不存在的情况,因此需要实现相应的错误处理逻辑,以便在查找失败时能够返回适当的错误信息或者值。

总的来说,实现C语言中哈希表的查找方法需要考虑哈希函数设计、冲突处理、具体的查找逻辑以及错误处理。

这些步骤需要根据具体的应用场景和数据特点来进行合理的设计和实现。

希望这些信息能够帮助到你理解C语言中哈希表的查找方法。

哈希表的工作原理

哈希表的工作原理

哈希表的工作原理哈希表(Hash Table)是一种基于哈希函数(Hash Function)实现的数据结构,用于快速存储和查找数据。

它的工作原理是通过将关键字映射到哈希值,然后将哈希值作为索引在内存中定位存储位置,从而实现快速的数据访问。

一、哈希函数的作用哈希函数是哈希表的核心,它负责将关键字映射为哈希值。

哈希函数应该具备以下几个特点:1. 确定性:对于相同的关键字,哈希函数应该始终得到相同的哈希值。

2. 均匀性:哈希函数应该能够将关键字均匀地映射到不同的哈希值上,以减少冲突的概率。

3. 高效性:哈希函数应该具备高效的计算性能,以尽快地获得哈希值。

二、哈希表的结构哈希表通常由一个固定大小的数组和哈希函数构成。

数组的大小是根据实际需求确定的,一般会根据数据规模的预估进行调整。

每个数组元素都被称为“桶”(Bucket)或“槽”(Slot),用于存储数据项。

三、哈希表的插入过程1. 根据关键字通过哈希函数计算出哈希值。

2. 将哈希值对数组的大小取模,得到在数组中的索引位置。

3. 判断该索引位置是否已经被占用:a. 如果该索引位置为空,则直接将数据项存储在该位置。

b. 如果该索引位置已经被占用,发生了冲突,需要解决冲突。

4. 解决冲突的方法主要有两种:a. 开放寻址法(Open Addressing):通过线性探测、二次探测等方法,在数组中寻找下一个可用的位置。

b. 链地址法(Chaining):在每个索引位置上维护一个链表,不同数据项通过链表连接在一起。

5. 若成功找到可用的位置或链表,在该位置或链表的末尾插入数据项。

四、哈希表的查找过程1. 根据关键字通过哈希函数计算出哈希值。

2. 将哈希值对数组的大小取模,得到在数组中的索引位置。

3. 判断该索引位置的数据项是否与待查找的关键字匹配:a. 如果匹配成功,则返回该数据项。

b. 如果匹配失败,发生了冲突,需要继续在该索引位置上进行查找。

4. 若使用的是链地址法,遍历链表中的每个数据项,逐个与待查找的关键字进行比较,直到找到匹配的数据项或到达链表的末尾。

哈希表数据结构

哈希表数据结构

哈希表数据结构哈希表是一种常用的数据结构,它可以将元素的添加、查找和删除的操作时间复杂度降至O(1),是一种快速、紧凑的数据结构。

它也可以被用于存储大量的键值对,如字典或者关联数组。

哈希表的内部结构有不同的实现方式,可以根据不同的实现方法达到不同的性能。

本文将详细介绍哈希表的背景、实现方式和应用等内容,以期使读者对哈希表有更深入的理解。

一、哈希表的概念哈希表是一种索引定位数据的数据结构。

哈希表(又称散列表)使用一种称为哈希函数的函数,根据键来计算出一个索引值,然后将值存储在数组的指定位置。

由于其有效的搜索时间,哈希表在许多不同的应用程序中被广泛的使用。

二、哈希表的实现方式哈希表的实现方式有多种,如拉链法、开放寻址法等,但其常用的实现方式为拉链法。

(1)拉链法拉链法是最基本的哈希表实现方式,它将散列值相同的键值(元素)存储在链表中,当需要查找或添加元素时只需要在链表中进行查找和操作,从而达到减少对查找和添加的时间复杂度。

拉链法中每个数组位置上存放一个链表的指针,链表中的每个节点中存放着存储的元素。

(2)开放寻址法开放寻址法是一种空间换时间的实现方式,它首先将输入的元素通过哈希函数映射成一个数组下标,如果该数组位置已经有数据存在,则重新使用哈希函数映射得到一个新的下标,直到找到一个没有被占用的位置将元素存放进去,以此来解决碰撞问题。

三、哈希表的应用哈希表在计算机科学中有着广泛的应用,它可以用来存储、查询和管理大量的键值对,如字典或者关联数组,减少查找的时间复杂度。

同时它也可以被用来存储表格数据,将表格转换成哈希表,使得查询性能更优。

此外,哈希表还可以被用来实现复杂的数据结构,如字典树,它可以帮助我们快速查询字符串是否存在。

总结哈希表是一种常用的数据结构,它可以将元素的添加、查找和删除的操作时间复杂度降至O(1),是一种快速、紧凑的数据结构。

它的实现方式主要有拉链法和开放寻址法,广泛应用于字典的存储、表格的查询和复杂的数据结构的实现等等。

哈希表实现方法

哈希表实现方法

哈希表实现方法
《哈希表实现方法》
哈希表是一种常用的数据结构,用于存储键值对,并且具有快速查找的特性。

在实际应用中,我们可以通过多种方法来实现哈希表,以下是几种常见的哈希表实现方法。

1. 直接寻址表
直接寻址表是一种最简单的哈希表实现方法,其核心思想是利用数组来存储键值对。

对于给定的键,通过一个哈希函数计算出相应的索引,然后将键值对存储在相应的位置。

这种方法的优点是简单易懂,但缺点是需要大量的内存空间。

2. 拉链法
拉链法是一种常用的哈希表实现方法,其核心思想是将哈希表的每个槽(slot)都连接一个链表。

当发生哈希冲突时,即多个键映射到同一个槽上时,将其存储在链表中。

这种方法的优点是能够很好地处理哈希冲突,但缺点是在大量数据情况下,链表长度可能会变得很长,导致查找效率变低。

3. 开放寻址法
开放寻址法是另一种常见的哈希表实现方法,其核心思想是当发生哈希冲突时,找到另一个空槽来存储键值对,而不是用链表来解决冲突。

具体的开放寻址方法包括线性探测、二次探测和双重哈希法等。

这种方法的优点是能够很好地处理哈希冲突,并且不需要额外的空间来存储链表,但缺点是可能会导致聚集现象,即一些槽会被频繁地访问。

以上是几种常见的哈希表实现方法,每种方法都有其特点和适用场景。

在实际应用中,我们可以根据具体的需求来选择合适的哈希表实现方法。

数据结构 哈希表的构建

数据结构 哈希表的构建

哈希表是一种基于哈希函数进行快速访问的数据结构,它可以在常数时间复杂度下进行插入、删除和查找操作。

下面是构建哈希表的一般步骤:
1. 定义哈希表的大小:首先,确定哈希表的大小,即桶的数量。

桶的数量应该是一个较大的素数,以减少哈希冲突。

2. 设计哈希函数:哈希函数是将输入的键转换为桶的索引的算法。

一个好的哈希函数应该能够将键均匀地映射到不同的桶中,以减少冲突。

常见的哈希函数包括除留余数法、乘法哈希法、平方取中法等。

3. 创建桶:根据确定的哈希表大小,创建相应数量的桶。

4. 插入操作:将键值对插入哈希表时,首先使用哈希函数计算出键对应的桶索引。

如果该桶为空,则将键值对插入该桶中;如果该桶非空,则发生冲突,需要解决冲突,常见的解决方法包括链地址法和开放地址法。

5. 查找操作:在查找键值对时,同样使用哈希函数计算出键对应的桶索引。

若该桶为空,则键不存在于哈希表中;若该桶非空,则可能存在冲突,需要在该桶中进行线性搜索或其他冲突解决方法来找到对应的值。

6. 删除操作:删除键值对时,先找到键对应的桶,然后删除桶中的键值对。

在实际应用中,为了提高哈希表的性能,通常还会考虑哈希表的动态扩容和缩容、哈希函数的设计优化、冲突解决策略的选择等问题。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

令胆嗲院计算机科嗲b练水系课程设计报告2007 2008 学年第 2 学期课程数据结构与算法课程设计名称哈希表的设计与实现学生姓名学号0604011026专业班级06计科(1)指导教师2008 年9 月课程设计题目:(哈希表的设计与实现的问题〉设计哈希表实现电话号码查询系统。

设计程序完成以下要求:(1)设每个记录有下列数据项:电话号码、用户名、地址:(2)从键盘输入各记录,分别以电话号码和用户名为关键字建立晗希表;(3)采用再哈希法解决冲突;(4)查找并显示给定电话号码的记录:(5)查找并显示给定用户的记录。

一、问题分析和任务定义1、问题分析要完成如下要求:设计晗希表实现电话号码查询系统。

实现本程序需要解决以下几个问题:(1) 如何设计一个结点使该结点包括电话号码、用户名、地址。

(2) 如何分别以电话号码和用户名为关键字建立哈希表。

(3) 如何利用再晗希法解决冲突。

(4) 如何实现用晗希法查找并显示给定电话号码的记录。

(5) 如何查找并显示给定用户的记录。

2、任务定义由问题分析知,本设计主要要求分别以电话号码和用户名为关键字建立晗希表,并实现查找功能。

所以本设计的核心问题是如何解决散列的问题,亦即设计一个良好的哈希表。

由于结点的个数无法确认,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题。

所以采用链地址法散列算法。

采用链地址法,当出现同义词冲突时,使用链表结构把同义词链接在一起,即同义词的存储地址不是散列表中其他的空地址。

决的是定义链表结点,在链地址法中,每个结点对应一个链表结点,它由三个首先,解域组成,而由于该程序需要分别用电话号码和用户名为关键字建立晗希表,所以该链表结点它是由四个域组成.name[8]、num[ll]和address[20]都是char浮点型,输入输出都只能是浮点型的。

采用链地址法,其中的所有同义词构成一个单链表,再由一个表头结点指向这个单链表的第一个结点。

这些表头结点组成一个一维数组,即哈希表。

数组元素的下标对应由散列函数求出的散列地址。

拉链法处理冲突的散列表结构:|||||3、主程序分析本题目最主要的要求是设计散列函数,本程序需要设计两个散列函数才能解决问题,程序需要分别为以电话号码和用户名为关键字建立哈希表。

所以要分别以用户名、号码为关键字建立两个散列画数,具体思路为:后对20求余。

得到的对于以号码为关键字的散列函数,是将十一个数字全部相加,然数作为地址。

对于以用户名为关键字的散列函数,是将所有字母的ASCLL码值相加,然后对20求余。

要添加用户信息,即要有实现添加结点的功能的函数,所以要设计一个必须包括一个输入结点信息、添加结点的函数:要实现查找函数,则必须包括一个查找结点的函数;另外还有一个必不可少的就是运行之后要有一个主菜单,即要设计一个主函数(mai n())。

4、测试数据的选择最后,程序完成后要对程序进行编译调试,执行后要选择数据进行测试,这里选择的测试数据为:l、姓名:张三电话号码:地址:合肥2、姓名:Jack 电话号码:地址:Shanghai三、概要设计和数据结构选择本设计涉及到的数据结构为:哈希表。

要求输入电话号码、用户名、地址三个信息,并要求分别以电话号码和用户名为关键字进行查找,所以本问题要用到两个晗希函数,进行哈希查找。

在链地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成,链地址法结点结构如图:|阳e[8]I川[口J l a抽出s[20] I next其中name[8]和num[ll]是分别为以电话号码和用户名为关键字域,存放关键字(key ) ; address[20](data)为结点的数据域,用来存储用户的地址。

Next指针是用来指向下一个结点的地址。

主要算法的流程图如下:以号码为关键字的H a s h()函数流程图开始取整型n um[2]赋给k eyi从3开始取Key=key+(int) num[i]i++Key=key%20结束以姓名为关键字的H ash O函数流程图/开始取整型name[O]赋给key2i从0开始取K ey2+=name[i]i++K ey2:::key%20结束添加结点信息流程图:开始申请新的结点 newp hone,newname 即新的号码和名字Newphone=input()Newname 指向n ewphone调用h ash()函数调用h ash()函数拉链法处理冲突利用用户名为关键字插入结束按姓名查找流程图:开始调用h ash()函数中新结点q指向phone[key]->nextq=q->n ext输出无记录q 不为空输出相应记录结束按号码查找流程图:开始调用b ash2()函数中新结点q指向pbone[key]->nextq=q->n ex t输出无记录q 不为空输出相应记录结束初始化散列链表 (1) 并为 其动态分配内存空 间初始化散列链表 ( 2) 并为 其动态分配内存空 间主程序流程图Menu () 主菜单结束进行姓名散1添加记录 a pend()进行号码散列 list ()号码散列 结果清空 creat();creat2()列表己清 空退出系统 return Ov .. . ..四、详细设计和编码首先定义结点结构体类型,在链地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成,链地址法结点结构如图:I n棚e[s]I川其中nam e[8]和num[ll]是分别为以电话号码和用户名为关键字域(k ey),存放关键字:a ddr ess[20]为结点的数据域(d ata),用来存储用户的地址信息。

n ex t指针是用来指向下一个结点的地址。

u n s ign e d in t k ey 和u n s ign e d in t k ey2 分别被定义为电话号码和用户名关键字。

程序的主要模块如下:*****串******************程序部分源代码中串*串*串*串*串*丰*************1、建立节点st ru ct node H建节点c har name[8],address[20]矿/节点中要包含用户名,用户地址,电话号码以及指向下一个结点的指针char num(ll];node * next;ty p e d ef node* pnode; //typedef 可以为一个己有的数据类型声明多个别名,这里为该类型声明了两个指针ty p e d ef node* mingzi;node **ph o ne ;node肺nam;nod e*a;2、对哈希函数的定义本程序要设计两个h as h O函数,分别对应电话号码和用户名。

本设计中对散列函数选择的是除留余数法,即对关键字进行模运算,将运算结果所得的余数作为关键字(或结点〉的存储地址,即************************程序部分源代码*牢牢牢牢牢牢牢牢牢牢串串串串串串串串*本*本*中a),•oid h as h(c har num[ll])II以电话号码为关键字建立哈希函数ke y=(int)num [2];while(num[i]!=NULL)ke y +=(int )num[i];1++;key =ke y %20;b )void bash2(c har name[8]) II 以用户名为关键字建立晗希函数int i = 1;key2=(int )name [O];while(name[i]!=NULL)ke y 2+=(int )name [i];’++;ke y 2=ke y 2%20;然后,建立结点 ,并添加结点用链地址法解决冲突 。

建立结点应包括动态申请内 存空间。

向结点中输入信息。

同时将结并且,需要两个建立散列链表的函数 ,分别动态申请一定的空间 ,用于动态申请散列 链表。

vo id creat β()用来动态创建以电话号码为关键字的链表数组,void create2()用来动态创 建以用户名为关键字的链表数组。

************串串**********程序部分源代码********************串*串*丰v oid create() II 新建号码节点 phone[i]=new nod e;phone[i]->next=NULL;int i ;phone =new pnode[20]; fl 动态创建对象数组for(i=O;i<20;i++)v oid create2() II新建姓名节点nam[i]=ne w node;int i; nam[i]->next=NULL ;nam=new mingzi[20];for(i=O;i<20;i叫同样,需要两个显示链表的函数,利用f or 循环和w hile 语句将表中信息按要求输出来。

3. 哈希查找想要实现查找功能,同样需要两个查找函数,无论以用户名还是以电话号码为关键字,果是以电话号码为关键字,比较首先,都需要利用h ash函数来计算出地址。

再通过比对,如其电话号码是否相同,如果相同则输出该结点的所有信息,如果以用户名为关键字,则比较用户名是否相同,如果相同则输出该结点的所有信息。

如果找不到与之对应相同的,则输出“无此记录,,。

************************程序部分源代码****串串*******************a)、void find(c har num[ll])施以电话号码为关键字的哈希表中查找用户信息hash(num);node *q=phone[ke y]->n ext;w hile(q!= NULL)if(s trcmp(num,q->num)==O)bre ak;q=q->ne x t;if(q)printf(”%s_%s_%s\n",q->name,q->a d dre邸q->num);el s e printf(无J1t记录飞n");b)、vo id f md2(c har name[S])II在以用户名为关键字的哈希表中查找用户信息hash2(nam e);node*q=nam[key2]->next;w hile(q!=NULL)i f(st r c mp(name,q->nam e)==O)break;q=q->next;if(q)q->nam e,q->addre ss,q->nUJD);printf(”%s_%s_%s恼”,el s e printf (无此记录飞n");3、主函数本程序需要创建一个主菜单和一个主函数,主菜单便于用户的使用,主函数中,包括所有功能对应的数值,使之和主菜单相对应。

相关文档
最新文档