哈希表实验报告完整版
哈希实验报告
![哈希实验报告](https://img.taocdn.com/s3/m/73249da7f9c75fbfc77da26925c52cc58bd690d3.png)
引言概述:本文旨在对哈希实验进行报告,重点介绍哈希实验的二次探测法、哈希函数、哈希表的查找、插入与删除操作,并分析实验结果。
通过本实验的开展,我们对哈希算法的原理、实现和性能有了更深入的理解,也增加了对数据结构的实践能力。
正文内容:一、二次探测法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.实验的意义与启示总结:通过对哈希实验的详细阐述,我们对二次探测法、哈希函数、哈希表的查找、插入与删除操作有了更深入的了解。
实验结果与分析表明,在哈希表的实现中,选择合适的哈希函数、解决哈希冲突以及优化插入与删除操作,对提高哈希表的性能至关重要。
哈希算法作为一种重要的数据结构应用,具有广泛的应用前景,在实际问题中具有重要的实践意义。
通过本次实验,我们不仅提升了对数据结构的理论理解,也增强了数据结构算法的实践能力,为今后的学习与研究打下了坚实的基础。
数据结构哈希表的实验报告
![数据结构哈希表的实验报告](https://img.taocdn.com/s3/m/8fa6dc93de80d4d8d05a4f82.png)
课程实习报告一、需求分析: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版)哈希表实现电话号码查询报告
![(完整word版)哈希表实现电话号码查询报告](https://img.taocdn.com/s3/m/a6b1a69f01f69e31423294a1.png)
《数据结构》课程设计报告书题目:哈希表存储的电话号码查询专业:学号:学生姓名:指导教师:完成日期:目录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总体设计本系统通过设计学生信息类和哈希表类来完成整个系统。
通过学生信息类实现从键盘输入学生的姓名,电话号码以及家庭地址.将学生的信息储存在建立的哈希节点内,通过多个链表保存,相同信息的保存在同一个节点内。
哈希表报告
![哈希表报告](https://img.taocdn.com/s3/m/19585b3fa22d7375a417866fb84ae45c3b35c2d2.png)
哈希表设计题目哈希表设计[问题描述]针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过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 。
哈希表实验报告
![哈希表实验报告](https://img.taocdn.com/s3/m/5082b576453610661ed9f4fc.png)
数据结构实验报告四——哈希表查找名字(字符串)实验题目:哈希表查找名字(字符串)实验目标:输入一组名字(至少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具体值由宏定义决定)。
哈希表实验报告
![哈希表实验报告](https://img.taocdn.com/s3/m/3603f494a58da0116c17497f.png)
实习报告题目:设计一个哈希表,完成相应的建表和查表程序一、班级: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++源码)
![哈希表(实验报告附C++源码)](https://img.taocdn.com/s3/m/08d93641cf84b9d528ea7ac9.png)
散列表一、问题描述我们希望在浩瀚的图书中,去发现一本书是否存在。
我们不知道书的编号,只知道它的书名。
(其实这已经不错了...)。
通过书名,来查询它是否存在。
为了简化问题,我们假设每本书的书名都是一组小写字母组成,长度不超过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;}算法的基本思想本程序采用了开散列表,用一个链表数组实现。
数据结构课程设计哈希表实验报告
![数据结构课程设计哈希表实验报告](https://img.taocdn.com/s3/m/8f5967d0aff8941ea76e58fafab069dc502247d9.png)
数据结构课程设计哈希表实验报告数据结构课程设计哈希表实验报告福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级: 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) //冲突处理函数,采用二次探测再散列法解决冲突{。
《哈希表》项目实验报告
![《哈希表》项目实验报告](https://img.taocdn.com/s3/m/250fe029b90d6c85ec3ac632.png)
《哈希表》项目实验报告1、实验名称哈希表问题2、小组成员刘艳宁、邓芳益;3、主要内容和步骤:(1)分析问题描述,明确问题目标对于一个哈希表,它是通过哈希算法,然后将数据按照哈希算法所得到的哈希地址存入到哈希表中。
所以对于一个哈希表,要了解它的存储方式、哈希表的冲突处理、数据的输入、数据的追加、哈希表的判空、哈希表清空、数据的查找(2)分析问题数据描述[数据描述]首先分析哈希表的构造方法:除留余数法取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址。
H(key)=key MOD p (p<=m);//哈希表的存储方法但是由于java中已经嵌入了哈希表,所以直接调用java中的哈希表:Import java.uilt.HashMap//调用java中的哈希表函数;(3)确定算法思路,准确描述算法[算法描述]首先运用java里面的哈希表;import java.util.Scanner;//调用java里面的Scanner供用户进行数据的输入import java.util.HashMap;//调用java哈希表根据公式:H(key)=key MOD p (p<=m)用输入的关键字来与哈希表的总长度来进行求余运算,然后将求得的余数存入到哈希表相应的位置中对于哈希表的查找:则根据哈希表的除留余数法然后进行数据的查找;当ASL为1时时最理想的,因为只需要查找一次,如果第一次没有查找到,则在先前的位置上加一进行查找,直到查找到数据为止然后返回。
(4)运行数据记录输入:学号:1000 姓名:张三输入:学号:1001 姓名:李四输出哈希表数据,然后进行判空,查找等操作(5)实验效果图示4、实验总结:(心得体会、处理结果、存在的问题、建议和意见等)心得体会:如果要实现哈希表的各个操作,首先要了解哈希表的存储方式;其次就是算法的构造上面,该程序是直接调用java中的hashmap,所以在算法上程序构造相对的比较简单。
哈希表的实验报告
![哈希表的实验报告](https://img.taocdn.com/s3/m/724c1c5a11a6f524ccbff121dd36a32d7375c7b9.png)
哈希表的实验报告哈希表的实验报告哈希表是一种常见的数据结构,用于存储和查找数据。
在本次实验中,我们将探索哈希表的原理、实现和性能,并通过实验验证其效果。
一、实验目的本次实验的目的是探索哈希表的原理和实现方法,并通过实验测试不同哈希函数和哈希表大小对性能的影响。
二、实验原理哈希表是一种基于哈希函数的数据结构,它将数据存储在数组中,通过哈希函数将数据映射到数组的特定位置。
哈希函数将数据转换为数组的索引,使得数据可以快速存储和查找。
哈希函数的选择很重要,一个好的哈希函数应该具备以下特点:1. 均匀性:哈希函数应该将数据均匀地分布到不同的索引位置,以避免冲突。
2. 高效性:哈希函数应该具有高效的计算速度,以提高哈希表的性能。
3. 低冲突:哈希函数应该尽可能减少冲突的发生,以提高哈希表的查找效率。
三、实验方法1. 实现哈希表:我们首先需要实现一个基本的哈希表数据结构。
哈希表可以使用数组来存储数据,每个数组元素称为一个桶,每个桶可以存储多个数据项。
在实现哈希表时,我们需要考虑如何处理冲突,常见的方法有链地址法和开放地址法。
2. 实现哈希函数:我们需要实现不同的哈希函数,以测试它们的性能。
常见的哈希函数包括除余法、乘法和平方取中法等。
我们可以通过实验比较它们的性能,选择最合适的哈希函数。
3. 测试性能:我们需要设计一系列实验,测试不同哈希函数和哈希表大小对性能的影响。
可以通过插入、查找和删除等操作来评估哈希表的性能。
我们可以记录每个操作的平均时间复杂度和空间占用情况,并绘制图表来展示结果。
四、实验结果与分析通过实验,我们得到了不同哈希函数和哈希表大小下的性能数据。
我们可以观察到不同哈希函数对性能的影响,并选择最优的哈希函数。
同时,我们还可以观察到哈希表大小对性能的影响,选择合适的哈希表大小以平衡性能和空间占用。
五、实验总结本次实验我们深入了解了哈希表的原理和实现方法,并通过实验验证了不同哈希函数和哈希表大小对性能的影响。
实验5 哈希表实验报告
![实验5 哈希表实验报告](https://img.taocdn.com/s3/m/adcb038ba0116c175f0e4812.png)
哈希表一、实验目的学会哈希函数的构造方法,处理冲突的机制以及哈希表的查找。
二、实验内容说明以下概念1、哈希函数在一般情况下,需在关键字与记录在表中的存储位置之间建立一个函数关系,以f(key) 作为关键字为key 的记录在表中的位置,通常称这个函数f(key) 为哈希函数。
1) 哈希函数是一个映象,即:将关键字的集合映射到某个地址集合上,它的设置很灵活,只要这个地址集合的大小不超出允许范围即可;2) 由于哈希函数是一个压缩映象,因此,在一般情况下,很容易产生“冲突”现象,即:key1≠ key2,而f(key1) = f(key2)。
2、哈希表根据设定的哈希函数f(key)和处理冲突的方法将一组关键字映像到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这种表便称为哈希表,这一映像过程称为哈希造表或散列,所得存储位置称哈希地址或散列地址。
3、冲突及处理1)冲突:对不同的关键字可能得到同意哈希地址,即key1≠ key2,而f(key1) = f(key2),这种现象称冲突(collision)。
2)处理方法:开放地址法。
4、哈希表的查找分析从查找过程得知,哈希表查找的平均查找长度实际上并不等于零。
决定哈希表查找的ASL 的因素:1) 选用的哈希函数;2) 选用的处理冲突的方法;3) 哈希表饱和的程度,装载因子 α=n/m 值的大小(n —记录数,m —表的长度)一般情况下,可以认为选用的哈希函数是“均匀”的,则在讨论ASL 时,可以不考虑它的因素。
因此,哈希表的ASL 是处理冲突方法和装载因子的函数。
可以证明:查找成功时有下列结果:线性探测再散列随机探测再散列从以上结果可见哈希表的平均查找长度是α的函数,而不是n 的函数。
这说明,用哈希表)111(21α-+≈nl S )1ln(1αα--≈nr S构造查找表时,可以选择一个适当的装填因子 ,使得平均查找长度限定在某个范围内。
完整word版,《数据结构》实验五哈希表
![完整word版,《数据结构》实验五哈希表](https://img.taocdn.com/s3/m/4d0baa1f9b6648d7c0c74652.png)
实验五查找一、实验目的(1)掌握哈希表的构造和查找过程及其算法设计;(2)掌握哈希表的平均查找长度的计算。
二、实验内容编写程序,实现哈希表的相关运算,并完成以下功能:(1)建立关键字序列(16,74,60,43,54,90,46,31,29,88,77)对应的哈希表A[0..12],哈希函数为H(k)=k%13,并采用开放地址法中的线性探测法解决冲突。
要求输出构造的哈希表。
(2)在上述哈希表中查找关键字为29的记录,输出其位置和比较次数;(3)在上述哈希表中删除关键字为77的记录,再将其插入。
(4)输出上述哈希表查找成功时的平均查找长度。
三、设计思路及程序代码(包括程序结构(即函数调用关系)、算法功能描述或流程图、程序代码)#include<stdio.h>#define MaxSize 100#define NULLKEY -1#define DELKEY -2typedef int KeyType;typedef char *InfoType;typedef struct{KeyType key;InfoType data;int count;}HashData;typedef HashData HashTable[MaxSize];void InsertHT(HashTable ha,int&n,KeyType k,int p)//将关键字k插入到哈希表中{int i,adr;adr=k%p;if(ha[adr].key==NULLKEY||ha[adr].key==DELKEY)//x[j]可以直接放在哈希表中{ha[adr].key=k;ha[adr].count=1;}else{i=1;do{adr=(adr+1)%p;i++;}while(ha[adr].key!=NULLKEY&&ha[adr].key!=DELKEY);ha[adr].key=k;ha[adr].count=i;}n++;}void CreateHT(HashTable ha,KeyType x[],int n,int m,int p)//创建哈希表{int i,n1=0;for(i=0;i<m;i++)//哈希表置初值{ha[i].key=NULLKEY;ha[i].count=0;}for(i=0;i<n;i++)InsertHT(ha,n1,x[i],p);}int SearchHT(HashTable ha,int p,KeyType k)//在哈希表中查找关键字k {int i=0,adr;adr=k%p;while(ha[adr].key!=NULLKEY&&ha[adr].key!=k){i++;//采用线性探查找下一个地址adr=(adr+1)%p;}if(ha[adr].key==k)//查找成功return adr;else return -1;//查找失败}int DeleteHT(HashTable ha,int p,int k,int &n)//删除哈希表中的关键字{int adr;adr=SearchHT(ha,p,k);if(adr!=-1)//在哈希表中找到该关键字{ha[adr].key=DELKEY;n--;//哈希表的长度减1return 1;}else//在哈希表中未找到该关键字return 0;}void DispHT(HashTable ha,int n,int m)//输出哈希表{float avg=0;int i;printf("哈希表的地址:\t");for(i=0;i<m;i++)printf("%3d",i);printf("\n");printf("哈希表的关键字为:\t");for(i=0;i<m;i++)if(ha[i].key==NULLKEY||ha[i].key==DELKEY)printf(" ");elseprintf("%3d",ha[i].key);printf("\n");}void ASL(HashTable ha,int n,int m,int p)//求平均查找长度{int i;int succ=0,unsucc=0;for(i=0;i<m;i++)if(ha[i].key!=NULLKEY)succ+=ha[i].count;//累计成功时的总关键字比较次数 printf("成功情况下ASL(%d)=%g\n",n,succ*1.0/n);}int main(){int x[]={16,74,60,43,54,90,46,31,29,88,77};int n=11,m=13,p=13,i,k=29;HashTable ha;printf("(1)\n");CreateHT(ha,x,n,m,p);//构造哈希表printf("\n");DispHT(ha,n,m);//输出哈希表printf("(2)\n");printf("查找关键字29的记录:\n");i=SearchHT(ha,p,k);if(i!=-1){printf("ha[%d].key=%d\n",i,k);printf("查找关键字29的比较次数为:%d\n",i);}elseprintf("未找到%d\n",k);printf("(3)\n");k=77;printf("删除关键字%d:\n",k);DeleteHT(ha,p,k,n);DispHT(ha,n,m);//输出哈希表i=SearchHT(ha,p,k);if(i!=-1)printf("ha[%d].key=%d\n",i,k);elseprintf("未找到%d\n",k);printf("将删除的关键字77重新插入:\n",k);//重新插入关键字77 InsertHT(ha,n,k,p);DispHT(ha,n,m);printf("(4)\n");printf("查找成功的平均长度为:\n");ASL(ha,n,m,p);return 0;}四、测试结果(程序运行结果采用截图的方式打印)五、实验体会(包括收获、心得体会、存在的问题及解决问题的方法、建议等)。
实验4—哈希表
![实验4—哈希表](https://img.taocdn.com/s3/m/29b39597daef5ef7ba0d3c40.png)
实验报告一、实验目的(1)掌握静态查找表和动态查找表的抽象数据类型特征。
(2)掌握将台查找表和动态查找表的实现方法。
(3)学会在顺序表、二叉排序树上设计查找算法,学会根据关键字特征设计哈希函数,设计哈希表,并实现哈希表查找过程。
二、实验内容与实验步骤[问题描述]真对你所在的集体(比如你所在的班级)中的人名设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表的程序。
[基本要求]假设人名为中国人姓名的汉语拼音形式,待填入的哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数方法构造,用伪随机探测再散列处理冲突。
[测试数据]取你周围熟悉的30个人的姓名。
[实现提示]如果随机函数自行构造,则应首先调整好随机函数,使其分布均匀。
人名的长度均不超过19个字符,最长的人名如:庄双双(Zhuang Shuangshuang)。
字符的取码方法可直接利用C语言中的toascii函数,并可对过长的人名先作折叠处理。
1 .存储结构定义typedef struct{ char *name; //名字所对应的拼音字母int k; //汉字拼音所对应的整数值}NAME;typedef struct //定义哈希表结构体{ char *name; //名字的拼音int k; //拼音所对应的整数int len; //查找的长度}HASH;2.姓名初始化名字以拼音的形式够成字符串,将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字。
void InitkName() //姓名初始化函数{//人名初始化如下kName[0].name="cunjian";kName[1].name="mayun";kName[2].name="wangshi";kName[3].name="sunfeng";kName[4].name="wangzhe";kName[5].name="dongxi";kName[6].name="shenme";kName[7].name="lijie";kName[8].name="xiaoqun";kName[9].name="liuyangdong";kName[10].name="wuhan";kName[11].name="zhuzhishan";kName[12].name="chendongming";kName[13].name="mayi";kName[14].name="huangxia";kName[15].name="wangyan";kName[16].name="zhoutao";kName[17].name="jiangzhenyu";kName[18].name="wangdan";kName[19].name="wangming";kName[20].name="chenjunbo";kName[21].name="lilei";kName[22].name="wangjia";kName[23].name="zhangjianguo";kName[24].name="zhuqingqing";kName[25].name="huangmin";kName[26].name="haoyuhan";kName[27].name="liutao";kName[28].name="zhujiang";kName[29].name="lijun";char *f;int r,s0,i;for(i=0;i<NUM;i++){ s0=0;f=kName[i].name;for(r=0;*(f+r)!='\0';r++){s0=*(f+r)+s0;}kName[i].k=s0;//将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字}}//初始化完成3.建立哈希表void CreateHashList() //建立哈希表函数{ int i;for(i=0; i<HASH_LENGTH;i++){ HashList[i].name=NULL;HashList[i].k=0;HashList[i].len=0;}for(i=0;i<HASH_LENGTH;i++){ int sum=0;int adr=(kName[i].k)%M;//哈希函数int d=adr;if(HashList[adr].len==0) //不冲突{HashList[adr].k=kName[i].k;HashList[adr].name=kName[i].name;HashList[adr].len=1;}else //发生冲突{do{ d=(d+kName[i].k%10+1)%M;//使用伪随机探测再散列法处理冲突 sum=sum+1; //查找次数加1}while (HashList[d].k!=0);HashList[d].k=kName[i].k;HashList[d].name=kName[i].name;HashList[d].len=sum+1;}}}4.查找哈希表void findList() //查找函数{ char name[20]={0};int s0=0,r,sum=1,adr,d;printf("请输入姓名的拼音:");scanf("%s",name);for(r=0;r<20;r++) //求出姓名的拼音所对应的整数,即关键字s0=name[r]+s0;adr=s0%M;d=adr;if(HashList[adr].k==s0)//分3种情况进行判断printf("\n查找完毕\n姓名:%s 关键字:%d ",HashList[d].name,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].name,s0,sum);g=1;}}while(g==0);}}5.显示哈希表void Display() // 显示哈希表{ int i;float average=0;printf("\n地址\t姓名\t\t\t\t搜索长度\t关键字\n"); //显示的格式for(i=0; i<50; i++){ printf("%d ",i);printf("\t %s ",HashList[i].name);printf("\t\t\t%d ",HashList[i].len);printf("\t\t%d ",HashList[i].k);printf("\n");}}6.主函数程序设计void main(){ char x;InitkName();CreateHashList();printf("\n--------这是一个哈希表查找系统-------\n");printf("请选择相应的操作:\n");while(1){ printf("1. 显示哈希表2. 查找3. 退出\n");cin>>&x;switch(x){case '1':Display(); cout<<endl;break;case '2':findList();cout<<endl;break;case '3':exit(0);}}}三、实验环境操作系统:windows7调试软件名称vc++6.0四、实验过程与分析你的查找过程的平均查找长度是多少?最坏情况下的查找长度是多少?答:平均长度为1.8 不超过规定的2。
哈希查找数据结构实验报告
![哈希查找数据结构实验报告](https://img.taocdn.com/s3/m/a59440e8294ac850ad02de80d4d8d15abe2300cd.png)
引言概述:哈希查找是一种高效的数据结构,它通过将关键字映射为哈希码,将数据存储在哈希表中,从而实现快速的查找操作。
本实验报告将详细介绍哈希查找的原理、实现方法、效率分析以及实验结果,并探讨其在实际应用中的优缺点。
正文内容:一、哈希查找的原理1.1哈希函数的选择1.2冲突处理方法1.3哈希表的结构和特性1.4哈希查找的流程和算法二、哈希查找的实现方法2.1开放寻址法2.1.1线性探测法2.1.2二次探测法2.1.3双重散列法2.2链地质法2.2.1链表的表示与操作2.2.2链地质法的实现步骤2.2.3链地质法的优化方法三、哈希查找的效率分析3.1平均查找长度(ASL)的计算3.2填装因子与性能的关系3.3平均查找长度的简化计算3.4哈希查找的时间复杂度与空间复杂度分析四、实验结果与分析4.1构建哈希表的过程4.2不同冲突处理方法比较4.3不同填装因子下的性能变化4.4实验结果的优化策略4.5实验结果与理论分析的对比五、哈希查找的应用与优缺点5.1应用领域5.2优点与不足5.3哈希查找与其他查找方法的比较5.4未来发展方向和改进方法总结:哈希查找是一种高效的数据结构,它通过将关键字映射为哈希码,将数据存储在哈希表中,实现快速查找。
本文详细介绍了哈希查找的原理、实现方法、效率分析以及实验结果,并探讨了其在实际应用中的优缺点。
通过实验分析和对比,我们可以得出结论:哈希查找在一定填装因子下有着较高的查找效率和较低的空间复杂度,适用于大规模数据的快速查找和插入操作。
哈希查找也存在着冲突处理问题和哈希函数设计的困难等不足之处。
未来的改进方向可以是优化冲突处理方法和进一步提高哈希函数的质量,以提升整体性能和应用范围。
散列表实验报告doc
![散列表实验报告doc](https://img.taocdn.com/s3/m/7e8038a16aec0975f46527d3240c844769eaa0a6.png)
散列表实验报告doc散列表实验报告篇一:数据结构实验散列表实验报告课程实验报告课程名称:实验项目名称:专业班级:姓名:学号:完成时间:月背景散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。
也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
这个映射函数叫做散列函数,存放记录的数组叫做散列表。
在理想情况下,查找、插入、删除操作的时间均为O(1),是一种高效的动态集合结构。
例1:计算机程序设计语言的编译程序需要维护一个符号表,其中元素的关键值为任意字符串,与语言中的标识符对应。
该符号表常采用散列表。
例2:为了节约空间,常常需要把文本文件采用压缩编码方式存储。
LZW是对文本文件进行压缩和解压缩的方法之一,该方法采用了散列。
问题描述我们希望在浩瀚的图书中,去发现一本书是否存在。
我们不知道书的编号,只知道它的书名。
(其实这已经不错了...)。
通过书名,来查询它是否存在。
为了简化问题,我们假设每本书的书名都是一组小写字母组成,长度不超过100字符。
基本要求(1)根据输入建立图书名称表,采用散列表实现该表,散列函数选用BKDE 字符串哈希。
(2)数据的输入输出格式:输入分为两部分第一部分,第一行是行数n,n 第二部分,第一行是行数m,m 输出:输出为m行,如果被查的记录存在,则输出"YES",如果不存在则输出"NO"。
测试数据输入:4aansandhellocppaban。
哈希表实验报告完整版
![哈希表实验报告完整版](https://img.taocdn.com/s3/m/de8e5075f56527d3240c844769eae009581ba232.png)
实验报告姓名:学号: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]。
哈希实验报告
![哈希实验报告](https://img.taocdn.com/s3/m/b5c0acd381c758f5f61f674b.png)
一、 问题描述1. 实验题目:利用哈希表统计两源程序的相似性2. 基本要求:1)内容: 对于两个 C 语言的源程序清单,用哈希表的方法分别统计两程序中使用C 语言关键字的情况,并最终按定量的计算结果,得出两份源程序的相似性。
2)要求与提示:C 语言关键字的哈希表可以自建,也可以采用下面的哈希函数作为参考: Hash(key)=(key 第一个字符序号*100+key 最后一个字符序号)%41表长m 取43。
此题的工作主要是扫描给定的源程序,累计在每个源程序中C 语言关键字出现的频度。
为保证查找效率,建议自建哈希表的平均查找长度不大于2。
扫描两个源程序所统计的所有关键字不同频度, 可以得到两个向量。
如下面简单的例子所示:根据程序1和程序2中关键字出现的频度,可提取到两个程序的特征向量X1和X2,其中 X1=(4 3 0 4 3 0 7 0 0 2)TX2=(4 2 0 5 4 0 5 2 0 1)T一般情况下,可以通过计算向量Xi 和Xj 的相似值来判断对应两个程序的相似性,相似值的判别函数计算公式为: ji Ti j i X X X X X S ⋅=)(,其中,i T i X X X ⋅=。
S(X i ,X j )的值介于[0,1]之间,也称广义余弦,即S(X i ,X j )=COSθ。
X i =X j 时,显见S(X i ,X j )=1,θ=0;X i X j 差别很大时,S(X i ,X j )接近0,θ接近π/2。
如X1=(1 0)T,X2=(0 1)T,则S(X i ,X j )=0,θ=π/2。
当S 值接近1 的时候,为避免误判相似性(可能是夹角很小,模值很大的向量),应当再次计算之间的“几何距离” D(X i ,X k )。
其计算公式为:)()(),(k i Tk i k i j i X X X X X X X X D --=-= 最后的相似性判别计算可分两步完成:第一步 用式(3-1)计算S ,把接近 1的保留,抛弃接近0的情况(把不相似的排除); 第二步 对保留下来的特征向量,再用式(3-2)计算D ,如D 值也比较小,说明两者对应的程序确实可能相似(慎重肯定相似的)。
- 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. 退出请输入正确的选择!。