哈希表实验报告完整版
哈希实验报告

引言概述:本文旨在对哈希实验进行报告,重点介绍哈希实验的二次探测法、哈希函数、哈希表的查找、插入与删除操作,并分析实验结果。
通过本实验的开展,我们对哈希算法的原理、实现和性能有了更深入的理解,也增加了对数据结构的实践能力。
正文内容:一、二次探测法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.实验的意义与启示总结:通过对哈希实验的详细阐述,我们对二次探测法、哈希函数、哈希表的查找、插入与删除操作有了更深入的了解。
实验结果与分析表明,在哈希表的实现中,选择合适的哈希函数、解决哈希冲突以及优化插入与删除操作,对提高哈希表的性能至关重要。
哈希算法作为一种重要的数据结构应用,具有广泛的应用前景,在实际问题中具有重要的实践意义。
通过本次实验,我们不仅提升了对数据结构的理论理解,也增强了数据结构算法的实践能力,为今后的学习与研究打下了坚实的基础。
数据结构哈希表的实验报告

课程实习报告一、需求分析:1.本程序来自于图书馆靠书名来检索想要查找的书问题。
2.本程序要求:(1)根据输入建立图书名称表,采用创建散列表实现。
(2)建散列表后,如果想要查找的数据在散列表中输出yes否则输出no。
二、哈希表简介结构中存在关键字和K相等的记录,则必定存储在f(K)的位置上。
由此,不需比较便可直接取得所查记录。
这个对应关系f称为散列函数(Hash function),按这个思想建立的表为散列表。
* 对不同的关键字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),这种现象称冲突。
具有相同函数值的关键字对该散列函数来说称做同义词。
* 综上所述,根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象”,作为这条记录在表中的存储位置,这种表便称为散列表,这一映象过程称为散列造表或散列,所得的存储位置称散列地址。
这个现象也叫散列桶,在散列桶中,只能通过顺序的方式来查找,一般只需要查找三次就可以找到。
科学家计算过,当负载因子(load factor)不超过75%,查找效率最高。
* 若对于关键字集合中的任一个关键字,经散列函数映象到地址集合中任何一个地址的概率是相等的,则称此类散列函数为均匀散列函数(Uniform Hash function),这就是使关键字经过散列函数得到一个“随机的地址”,从而减少冲突。
程序设计流程程序思想(一)哈希函数unsigned int hash_BKDE(char *str)生成映射地址,成为散列表的编号。
(二)哈希表HashTable::HashTable()通过数组储存元素(三)插入函数void HashTable::insert(char*c)插入字符串,先计算要插入字符串生成的映射地址,然后在相应的地址插入,如果没有空位查找空位插入。
(四)查找函数bool HashTable::find(char*c)进行查找,先计算要生成字符串的地址,再到散列表中进行查找比较。
(完整word版)哈希表实现电话号码查询报告

《数据结构》课程设计报告书题目:哈希表存储的电话号码查询专业:学号:学生姓名:指导教师:完成日期:目录1.实训题目………………………………………………1。
1实训要求…………………………………………. 1。
2需求分析…………………………………………。
2.系统设计………………………………………………2。
1总体设计………………………………………….. 2。
2详细设计…………………………………………。
2。
2。
1程序头文件…………………………………。
2。
2.2学生信息类及哈希表类……………………。
.2.2.3主函数流程…………………………………。
. 3。
系统实现………………………………………………。
3.1编码………………………………………………。
3。
2测试………………………………………………。
4。
归纳总结……………………………………………….4.1实训中遇到的问题以及解决办法………………。
.4.2感想和心得体会…………………………………。
5。
参考资料………………………………………………1.实训题目1.1实训要求⏹设每个记录有以下数据项:用户名、电话、地址;⏹从键盘输入各记录,以电话号码为关键字建立哈希表;⏹采用链地址法方法解决冲突;⏹能够查找并显示给定电话号码的相关记录。
1。
2需求分析本次实验要求采用哈希表完成信息的查找和储存,哈希表即为散列表。
本程序采用学生信息管理为例,设每个学生有电话号码,学生姓名,家庭住址三个信息。
通过建立哈希表储存信息,信息储存在节点中,并通过以电话号码为关键字完成查找,并显示出该学生的姓名,电话号码以及家庭住址.当哈希表中的数据与输入的数据发生冲突时,使用节点向后移一位的方法来解决冲突。
2.系统设计2.1总体设计本系统通过设计学生信息类和哈希表类来完成整个系统。
通过学生信息类实现从键盘输入学生的姓名,电话号码以及家庭地址.将学生的信息储存在建立的哈希节点内,通过多个链表保存,相同信息的保存在同一个节点内。
哈希表报告

哈希表设计题目哈希表设计[问题描述]针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
[基本要求]假设人名为中国姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
构造哈希函数,用链表法处理冲突。
[测试数据]读取熟悉的30个人的姓名作测试。
一.需求分析:1. 针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
2. 人名为中国姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
3. 用每个名字各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字,用除余法构造哈希函数,用拉链法处理冲突。
4.输入数据:zhaoxuening ,muchunyang ,lvzhihui,jiangbiwen,zhangye ,libaoling,yulin,wangjie,huangzheng,xiahaiyun,tanyongli,yangjiaqi,liufengbin,wangfeng,huangweilun,chenliang,hezhicong,yaochengzhong,chaozhihao,wangshipeng,ganyongze,luyang,baichongliang,zhurui,chenyiming,pengxuan,equanming,lishiwei,baitian,wuliao。
5.测试数据:lishiwei,zhurui,abcdefg,wangshipeng二.概要设计1.程序流程图2.存储结构:名字表:struct Name{ //名字表char *name; //名字int key; //关键码}哈希表:struct Node;typedef struct Node * PNode;struct Node{ //每条单链表结点结构定义char *name;PNode link;};struct HashDic{ //哈希表结构定义PNode llist[P]; //哈希表所包含的单链表,P为基本区域长度float search; //总查找长度float total; //哈希表中名字数int m; //哈希表长度};};typedef struct HashDic *PHashDic; //哈希表类型3.主要算法: (1). int h(char *py){ }//除余法,返回名字在哈希表中的相应地址(2) PHashDic create_EmptyDic(){ } //创建空哈希表(3)void insert_node(PHashDic phash,char *py) { } //插入算法(4)void search_node(PHashDic phash){ } //查找算法(5)void delete_node(PHashDic phash){ } //删除算法(6)void output_name(){ } //输出姓名表(7)void output_hash(PHashDic phd){ } //输出哈希表(8)void InitNameTable(){ } //姓名表的初始化(9)void print(){ } //打印操作菜单(10)void main(){ } //主函数三.详细设计1. 除余法,返回名字在哈希表中的相应地址int h(char *py){int key;for (int i=0;i<NAME_LEN;i++) //将字符串的各个字符所对应的ASCII码相加,所得的整数做为名字的关键字{int s=0;char *p=py;for (int j=0;*(p+j)!='\0';j++)s+=int(*(p+j));key=s;}return key%P;}2. 创建空哈希表PHashDic create_EmptyDic(){PHashDic phash=(PHashDic)malloc(sizeof(struct HashDic));int i;phash->search=0;phash->total=0;phash->m=P;for(i=0;i<phash->m;i++){phash->llist[i]=NULL;}return phash;}3. 插入算法void insert_node(PHashDic phash,char *py){PNode p,q;int r=1; //查找长度大于2的py的查找长度nt adr=h(py);if(phash->llist[adr]==NULL){ //如果单链表为空,向单链表插入第一个元素p=(PNode)malloc(sizeof(struct Node)); //创建新结点p->name=py;p->link=NULL;phash->llist[adr]=p;phash->total++;phash->search+=1;return;}q=phash->llist[adr];if (strcmp(q->name,py)==0) //如果已有此元素则不再插入{cout<<"名字已经存在"<<endl;return;}while (q->link!=NULL){if(strcmp(q->link->name,py==0{cout<<"名字已经存在"<<endl;return;}q=q->link;r++;}p=(PNode)malloc(sizeof(struct Node)); //否则就插入单链表最后p->name=py;p->link=NULL;q->link=p;r++;phash->search+=r;phash->total++;}4. 查找算法void search_node(PHashDic phash){PNode p;int adr,r; //哈希表地址和查找长度char py[20];cout<<"请输入要查找的名字:\n";cin>>py;adr=h(py);if(phash->llist[adr]==NULL) cout<<"查找结果:\n"<<"没有想要查找的人!!\n";//如果相应单链表为空,则没有所要查找的名字else {p=phash->llist[adr];while(strcmp(p->name,py)!=0 && p->link!=NULL)//否则对比单链表内容直到查找到名字或对比完单链表中数据{p=p->link;r++;}if(strcmp(p->name,py)==0)cout<<"查找结果:\n"<<"名字:"<<py<<" 地址"<<adr<<" 查找长度"<<r<<endl;//查找到名字else cout<<"查找结果:\n"<<"没有想要查找的人\n"; //对比完单链表中数据,没有该名字}}5. 删除算法void delete_node(PHashDic phash){PNode p,q;int r=1; //查找长度char py[20]={0};cout<<"请输入要删除的名字:\n";cin>>py;int adr=h(py);if(phash->llist[adr]==NULL) //如果相应单链表为空,则没有所要删除的名字{cout<<"没有想要删除的名字!!\n";return;}p=phash->llist[adr];if(strcmp(p->name,py)==0) //如果要删除的是单链表第一个元素{phash->llist[adr]=p->link;free(p);cout<<"删除完成!!\n";phash->total--;phash->search-=1;return;}while(p->link!=NULL && strcmp(p->link->name,py)!=0 )//否则对比单链表内容直到查找到名字或对比完单链表中数据{p=p->link;}if(strcmp(p->link->name,py)==0) //查找到名字{q=p->link;p->link=q->link;free(q);cout<<"删除完成!!\n";r++;phash->search-=r;phash->total--;return;}else //对比完单链表中数据,没有该名字{cout<<"没有想要删除的名字!!\n";return;}}6. //输出姓名表void output_name(){ //输出姓名表int i;printf("序号\t\t 姓名\t\t 关键字\n");for (i=0;i<NAME_LEN;i++)printf("%2d %18s \t\t %d \n",i,NameTable[i].name,NameTable[i].key); }7.输出哈希表void output_hash(PHashDic phd){ //输出哈希表PNode p;float ASL; //平均查找长度nt i;cout<<"地址名字\n";for (i=0;i<P;i++){p=phd->llist[i];cout<<i;while(p!=NULL){cout<<" 一> "<<p->name;p=p->link;}cout<<endl;}ASL=phd->search/phd->total;cout<<"平均查找长度:"<<ASL<<endl;}8. 姓名表的初始化void InitNameTable(){NameTable[0].name="zhaoxuening";NameTable[1].name="muchunyang";NameTable[2].name="lvzhihui";NameTable[3].name="jiangbiwen";NameTable[4].name="zhangye";NameTable[5].name="libaoling";NameTable[6].name="yulin";NameTable[7].name="wangjie";NameTable[8].name="huangzheng";NameTable[9].name="xiahaiyun";NameTable[10].name="tanyongli";NameTable[11].name="yangjiaqi";NameTable[12].name="liufengbin";NameTable[13].name="wangfeng";NameTable[14].name="huangweilun";NameTable[15].name="chenliang";NameTable[16].name="hezhicong";NameTable[17].name="yaochengzhong";NameTable[18].name="chaozhihao";NameTable[19].name="wangshipeng";NameTable[20].name="ganyongze";NameTable[21].name="luyang";NameTable[22].name="baichongliang";NameTable[23].name="zhurui";NameTable[24].name="chenyiming";NameTable[25].name="pengxuan";NameTable[26].name="equanming";NameTable[27].name="lishiwei";NameTable[28].name="baitian";NameTable[29].name="wuliao";for (int i=0;i<NAME_LEN;i++)//将字符串的各个字符所对应的ASCII码相加,所得的整数做为名字的关键字{int s=0;for (int j=0;NameTable[i].name[j]!='\0';j++)s+=int(NameTable[i].name[j]);NameTable[i].key=s;}}9. 打印操作菜单void print(){cout<<" ********************************************************\n";cout<<" 操作菜单\n";cout<<" 1.输出姓名表\n";cout<<" 2.输出哈希表\n";cout<<" 3.查找\n";cout<<" 4.删除\n";cout<<" 5.插入\n";cout<<" 6.退出\n";cout<<" ********************************************************\n"; }10.主函数void main(){int i,c,k=0;PHashDic phash=create_EmptyDic(); //创建空哈希表phashInitNameTable();for (i=0;i<NAME_LEN;i++) //将名字表中的名字存入哈希表insert_node(phash,NameTable[i].name);print(); //打印操作菜单cout<<"请选择操作:";cin>>c;while(c!=1&&c!=2&&c!=3&&c!=4&&c!=5&&c!=6) {cout<<"请重新选择操作:";cin>>c;}do{//当选择6时结束算法,选择1,2,3,4,5则执行相应操作直到结束switch(c){case 1:output_name();print();break; //输出姓名表case 2: output_hash(phash);print();break; //输出哈希表case 3:search_node(phash);print();break; //查找case 4:delete_node(phash);print();break; //删除case 5:{char py[20]; //插入cout<<"请输入要插入的名字:\n";cin>>py;insert_node(phash,py);}print();break;case 6:cout<<"已退出\n";break;default:cout<<"\n请输入正确的选择!\n:";}if(c!=6){cout<<"请选择操作:";cin>>c;while(c!=1&&c!=2&&c!=3&&c!=4&&c!=5&&c!=6){cout<<"请重新选择操作:";cin>>c;}}}while (c==1||c==2||c==3||c==4||c==5); }四.调试分析1.输出姓名表2.输出哈希表3.查找:lishiwei和abcdefg4.删除:lishiwei,zhurui,abcdefg5.插入:abcdefg和wangshipeng6.退出五.课程设计总结算法分析及改进:1. 由于要对哈希表进行插入,删除等操作字典元素处于动态,而且名字出现无规律可言,因此采用除余法构造哈希函数h(x) = x mod P 。
哈希表实验报告

数据结构实验报告四——哈希表查找名字(字符串)实验题目:哈希表查找名字(字符串)实验目标:输入一组名字(至少50个),将其保存并利用哈希表查找。
输出哈希查找冲突次数,哈希表负载因子、查找命中率。
数据结构:哈希表和数组(二维)。
二维数组用于静态顺序存储名字(字符串),哈希表采用开放定址法,用于存储名字(字符串)对应的关键字并实现对名字(字符串)的查找。
需要的操作有:1.关键字求取(主函数中两次出现,未单独编为函数)关键字key=abs(字符串首位ASCII码值-第二位ASCII码值+第([]+1)位ASCII码值-最后一位ASCII码值-倒数第二位ASCII码值)*字符串长度(abs为求整数绝对值的函数)。
2.处理关键字的哈希函数(Hash)利用平方取中法求关键值key在哈希表中的位置。
公式add=(key*key)%1000/LENGTH(add 为key在哈希表中的地址)。
int Hash(int key){return((key*key)/1000%LENGTH);}3.处理哈希表中冲突的函数(Collision)利用线性探测再散列处理冲突,利用全局变量count统计冲突次数。
int Collision(int key,int Hashtable[]){int i;for(i=1;i<=LENGTH;i++){if(Hashtable[(Hash(key)+i)%LENGTH]==-1)return((Hash(key)+i)%LENGTH);count++;}}4.哈希表初始化(InitHash)void InitHash(int Hashtable[]){int i;for(i=0;i<LENGTH;i++)Hashtable[i]=-1;}5.向哈希表中插入关键字(InsertHash)void InsertHash(int key,int Hashtable[]){int add;if(Hashtable[add]==-1)Hashtable[add]=key;else{add=Collision(key,Hashtable);Hashtable[add]=key;}}6.查找关键字在哈希表中的存储位置(SearchHash)int SearchHash(int key,int Hashtable[]){int add;add=Hash(key);if(Hashtable[add]==key)return add;while(Hashtable[add]!=key&&Hashtable[add]!=-1)add=Collision(key,Hashtable);return add;}7.输出哈希表(PrintHash)(帮助调试用)void PrintHash(int Hashtable[]){int i;for(i=0;i<LENGTH;i++)if(Hashtable[i]!=-1)printf("%3d:%d\n",i+1,Hashtable[i]);}8.求字符串长度(strlen)(函数库<string.h>包含)以及求整数的绝对值(abs)(函数库<math.h>包含)算法设计:1建立长度为LENGTH的哈希表Hash(LENGTH具体值由宏定义决定)。
哈希表实验报告

实习报告题目:设计一个哈希表,完成相应的建表和查表程序一、班级:1503013 姓名:李睿元学号:完成日期:需求分析1. 假设人名为中国人名的汉语拼音形式;2. 待填入哈希表的姓名共有30个,去平均查找长度的上限为2;3. 哈希函数用除留余数法构造,用伪随机探测再散列法处理冲突;4. 取读者周围较熟悉的30个人的姓名。
二、概要设计1. 抽象数据类型的定义:(1)人名数据表:typedef struct Node{char name[20];int key;}Node,NodeList[MAX];(2)哈希表:typedef struct hashtable{char* name;int key;int conflict_time;}HashTable[hashlen];(3)变量:#define P 61主要函数的实现:(1)哈希函数:int Hash(int key)(2)关键字获得:int GetKey(char str[])(3)文件流中读取姓名:void GetName(NodeList &L,int i,FILE* fp)(4)哈希表的初始化:void InitialHashTable(HashTable &ht)(5)伪随机探测序列的生成:void CreatConfilctArray(int n[])(6)哈希表的生成:void CreatHashTable(HashTable &ht,NodeList L,int* n)(7)哈希表的查询:void SearchHashTable(HashTable ht,int* n,char get_name[])三、详细设计#include <>#include <>#include <>#define P 61ame);L[i].key=GetKey(L[i].name); */fscanf(fp,"%s",L[i].name);L[i].key=GetKey(L[i].name);onflict_time=0;ht[n].name=NULL;ht[n].key=0;n++;}}void CreatConfilctArray(int n[]){ey);if(ht[t].conflict_time==0){ht[t].name=L[i].name;ht[t].conflict_time++;ht[t].key=L[i].key;printf("姓名:%s key值:%d 表内存储位置:%d\n",L[i].name,L[i].key,t);}else{int m=0;int d=(t+n[m])%hashlen;while(ht[d].conflict_time!=0){ht[d].conflict_time++;m++;d=(t+n[m])%hashlen;}ht[d].name=L[i].name;ht[d].conflict_time++;ht[d].key=L[i].key;printf("姓名:%s key值:%d 表内存储位置:%d\n",L[i].name,L[i].key,d);}i++;}}void SearchHashTable(HashTable ht,int* n,char get_name[]){onflict_time==0&&ht[h].key!=k){printf("表中未找到无此人!\n");break;}else if(ht[h].key==k){printf("已找到%s,表内存储位置:%d\n",get_name,h);break;}else{p++;h=n[p];}*/if(ht[h].name==NULL){printf("表中未找到无此人!\n");break;}else if(strcmp(ht[h].name,get_name)==0){printf("已找到%s,表内存储位置:%d,查找次数:%d\n",get_name,h,s_time);break;}else{p++;h=(t+n[p])%hashlen;s_time++;}}}int main(){哈希表可以在理想情况下不经过任何比较,一次存取就能得到所查记录;2. 除留余数法对于p的选择很重要,经过分析后的选择是p为小于等于m的最大素数,最终选择了61;3. 伪随机探测再散列相较于线性探测再散列或二次探测再散能有效的防止二次堆积。
哈希表(实验报告附C++源码)

散列表一、问题描述我们希望在浩瀚的图书中,去发现一本书是否存在。
我们不知道书的编号,只知道它的书名。
(其实这已经不错了...)。
通过书名,来查询它是否存在。
为了简化问题,我们假设每本书的书名都是一组小写字母组成,长度不超过100字符。
二、需求分析1.根据输入建立图书名称表,采用散列表实现该表,散列函数自建。
2.数据的输入输出格式:输入分为两部分输入:第一部分,第一行是行数n,n <= 5000。
余下n行,每行一个字符串。
表示已存在的图书记录。
第二部分,第一行是行数m,m <= 1000。
余下m行,每行一个字符串。
表示要查询的图书记录。
输出:输出为m行,如果被查的记录存在,则输出"YES",如果不存在则输出"NO"。
3.测试数据输入:4aansandhellocpp9abanasansandandehellocbbhellocpp输出:YESNONONOYESYESNONOYES三、概要设计抽象数据类型class Node//最基本的抽象数据类型{public:char ch[20];//链表中,记录表中数据,20为查找字符串的长度Node* next;//指向下一个结点Node(const char* in);//构造函数};class List{ //用Node作结点的链表public:Node* head;Node* tail;Node* fence;List();~List();bool append(const char* in);//像链表中,增添结点};class Hash//哈希表的详细设计{private:List* myList;//指向链表数组public:int getSubInt(const char* in) const; //哈希函数,把传进的字符串的ASCII//相加,再mod哈西表大小,得该字符串的位置Hash();~Hash();bool insert(const char*) const;//建立哈希表bool find(const char*) const;//在哈希表中查找};int Hash::getSubInt(const char *in) const//哈希函数的实现{int sum=0,i=0;while(in[i]!='\0')sum+=in[i++];return sum%tableSize;}算法的基本思想本程序采用了开散列表,用一个链表数组实现。
数据结构课程设计哈希表实验报告

数据结构课程设计哈希表实验报告数据结构课程设计哈希表实验报告福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级: xxxxxx班座号: xxxxxxxxxxxx姓名: xxxxxxx12 月 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) //冲突处理函数,采用二次探测再散列法解决冲突{。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告姓名:学号:1.实验题目针对某个集体中人名设计一个哈希表,使得平均查找长度不超过R,并完成相应的建表和查表程序。
基本要求:假设人名为中国人姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突。
2.需求分析本演示程序用VC编写,完成哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突。
输出形式:地址,关键字,收索长度,H(key),拼音3.概要设计typedef struct NAMEtypedef struct htermvoid InitNameList()void CreateHashList()void FindList()void Display()int main()4.详细设计#include <stdio.h>#include<malloc.h>#include<string.h>#define HASH_LEN 50#define M 47#define NAME_NO 8typedef struct NAME{char *py; //名字的拼音int k; //拼音所对应的整数}NAME;NAME NameList[HASH_LEN];typedef struct hterm //哈希表{char *py; //名字的拼音int k; //拼音所对应的整数int si; //查找长度}HASH;HASH HashList[HASH_LEN];void InitNameList(){NameList[0].py="houxinming"; NameList[1].py="abc"; NameList[2].py="defdgf"; NameList[3].py="zhangrji"; NameList[4].py="jiaxin"; NameList[5].py="xiaokai"; NameList[6].py="liupeng"; NameList[7].py="shenyonghai";char *f;int r,s0;for (int i=0;i<NAME_NO;i++)// 求出各个姓名的拼音所对应的整数{s0=0;f=NameList[i].py;for (r=0;*(f+r) != '\0';r++) //方法:将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字s0=*(f+r)+s0;NameList[i].k=s0;}}void CreateHashList(){for ( int i=0; i<HASH_LEN;i++)//哈希表的初始化{HashList[i].py="";HashList[i].k=0;HashList[i].si=0;}for ( i=0; i<NAME_NO;){int sum=0;int adr=(NameList[i].k) % M; //哈希函数int d=adr;if(HashList[adr].si==0) //如果不冲突{HashList[adr].k=NameList[i].k;HashList[adr].py=NameList[i].py;HashList[adr].si=1;}else //冲突{do{d=(d+((NameList[i].k))%10+1)%M; //伪散列sum=sum+1; //查找次数加1}while (HashList[d].k!=0);HashList[d].k=NameList[i].k;HashList[d].py=NameList[i].py;HashList[d].si=sum+1;}i++;}}void FindList(){printf("\n\n请输入姓名的拼音: "); //输入姓名char name[20]={0};scanf("%s",name);int s0=0;for (int r=0;r<20;r++) //求出姓名的拼音所对应的整数(关键字) s0+=name[r];int sum=1;int adr=s0 % M; //使用哈希函数int d=adr;if(HashList[adr].k==s0) //分3种情况进行判断printf("\n姓名:%s 关键字:%d 查找长度为: 1",HashList[d].py,s0); else if (HashList[adr].k==0)printf("无该记录!");else{int g=0;do{d=(d+s0%10+1)%M; //伪散列sum=sum+1;if (HashList[d].k==0){printf("无记录! ");g=1;}if (HashList[d].k==s0){printf("\n姓名:%s 关键字:%d 查找长度为:%d",HashList[d].py,s0,sum);g=1;}}while(g==0);}}void Display(){printf("\n\n地址\t关键字\t\t搜索长度\tH(key)\t\t拼音\n"); //显示的格式for(int i=0; i<15; i++){printf("%d ",i);printf("\t%d ",HashList[i].k);printf("\t\t%d ",HashList[i].si);printf("\t\t%d ",(HashList[i].k)%M);printf("\t %s ",HashList[i].py);printf("\n");}for( i=15; i<30; i++){printf("%d ",i);printf("\t%d ",HashList[i].k);printf("\t\t%d ",HashList[i].si);printf("\t\t%d ",(HashList[i].k)%M);printf("\t %s ",HashList[i].py);printf("\n");}for( i=30; i<40; i++){printf("%d ",i);printf("\t%d ",HashList[i].k);printf("\t\t%d ",HashList[i].si);printf("\t\t%d ",(HashList[i].k)%M);printf("\t %s ",HashList[i].py);printf("\n");}for(i=40; i<50; i++){printf("%d ",i);printf("\t%d ",HashList[i].k);printf("\t\t%d ",HashList[i].si);printf("\t\t%d ",(HashList[i].k)%M);printf("\t %s ",HashList[i].py);printf("\n");}float average=0;for (i=0;i<HASH_LEN;i++)average+=HashList[i].si;average/=NAME_NO;printf("\n\n平均查找长度:ASL(%d)=%f \n\n",NAME_NO,average); }int main(){printf("\n------------------------哈希表的建立和查找----------------------"); InitNameList();CreateHashList ();while(1){printf("\n\n");printf(" 1. 显示哈希表\n");printf(" 2. 查找\n");printf(" 3. 退出\n");err:char ch1;scanf("%c",&ch1);if (ch1=='1')Display();else if (ch1=='2')FindList();else if (ch1=='3')return 0;else{printf("\n请输入正确的选择!");goto err;}}}5.调试分析(略)6.使用说明程序名为hash tablet.exe,运行环境为DOS。
程序执行后显示========================1.显示哈希表2.查找3.退出=======================SELECT:在select后输入数字选择执行不同的功能。
要求首先输入足够多的插入元素,才可以进行其他的操作。
每执行一次功能,就会显示执行的结果(正确或错误)以及执行后单链表的内容。
选择1:显示哈希表选择2:显示请输入姓名的拼音,要求输入要删除元素的位置,执行成功后返回元素的值。
选择3:退出程序7.测试结果------------------------哈希表的建立和查找----------------------1. 显示哈希表2. 查找3. 退出1地址关键字搜索长度H(key) 拼音0 0 0 01 0 0 02 0 0 03 0 0 04 756 1 4 liupeng5 0 0 06 1181 1 6 shenyonghai7 0 0 08 0 0 09 0 0 010 0 0 011 0 0 012 294 1 12 abc13 1094 1 13 houxinming14 0 0 015 861 1 15 zhangrji16 0 0 017 0 0 018 0 0 019 0 0 020 0 0 021 0 0 022 0 0 023 0 0 024 0 0 025 0 0 026 0 0 027 0 0 028 0 0 029 0 0 030 0 0 031 0 0 032 643 1 32 jiaxin33 0 0 034 0 0 035 0 0 036 0 0 037 742 1 37 xiaokai38 0 0 039 0 0 040 0 0 041 0 0 042 0 0 043 0 0 044 608 1 44 defdgf45 0 0 046 0 0 047 0 0 048 0 0 049 0 0 0平均查找长度:ASL(8)=1.0000001. 显示哈希表2. 查找3. 退出请输入正确的选择!2请输入姓名的拼音: houxinming姓名:houxinming 关键字:1094 查找长度为: 11. 显示哈希表2. 查找3. 退出请输入正确的选择!。