数据结构课程设计--哈希表实验报告
课程设计试验报告-哈希表的设计与实现
数据结构课程设计题目哈希表的设计与实现作者院系信息工程学院专业信息管理与信息系统学号1514210117指导老师张慧答辩时间2016年12月18日目录数据结构课程设计01系统需求分析11.1用户需求分析21.2功能需求分析21.3数据需求分析21.4 小结32系统设计32.1设计内容及要求32.2总体设计思路32.3程序详细设计流程图42.31以姓名为关键字的Hash()函数流程图42.32添加结点信息流程图:52.33按姓名查找流程图:62.34按号码查找流程图62.35主程序流程图72.4详细设计编码92.41建立节点92.42对哈希函数的定义92.43哈希查找92.44主函数103系统测试113.1上机调试113.2调试结果与分析114总结155附录151系统需求分析在信息化时代的今天,计算机技术已经是发展到一个很可观的地步了,特别是面向窗口的操作系统的出现,使得程序设计更加的容易了。
在过去计算机内存容量小,CPU计算速度慢,关于程序设计中的数据结构也因此提出来很多的关于解决这方面的问题。
哈希表就是其中之一,哈希表是一个由关键字与值组成的特殊的一种数据结构。
它的出现主要是为了解决在结构中查找记录时需要进行一系列和关键字的比较,这一类查找方法是建立在“比较”的基础上的,在顺序等的查找中,查找的效率是依赖于查找过程中所比较的次数。
理想的情况是希望不经过任何的比较一次存取便能得到所查记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系,使得每个关键字和结构中一个唯一的存储位置相对应。
因而在查找时只要根据这个对应关系找到给定的值的像。
若结构中存在关键字和该值相等的记录,则所要查找的数就必定就是这个所查找到的记录。
哈希函数是建立哈希表的一个重要的成员,它的构造方法分为以下几种:直接定址法、数字分析法、平方取中法、折叠法、除留余数法、随机数法。
本程序中主要用的是除余取留法,除留取余法主要是取关键字被某个不大于哈希表表长m的数p出后所得余数为哈希地址即:H(key)=key MOD p, p<=m,这是一种最简单,也是一种最常用的构造函数的方法,它不仅可以对关键字直接取模,也可在折叠、平方中等运算之后取模。
大数据结构课程设计--哈希表实验报告材料
福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级: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();void CreateHash1(HashTable* H,Record* a) //建表,以人的姓名为关键字,建立相应的散列表{ int i,p=-1,c,pp;system("cls"); //若哈希地址冲突,进行冲突处理benGetTime();for(i=0;i<NUM_BER;i++){c=0;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。
数据结构课程设计--哈希表实验报告
福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级: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.本程序要求:(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)进行查找,先计算要生成字符串的地址,再到散列表中进行查找比较。
《数据结构》课程设计-哈希表设计
目录课程设计任务书 01.问题描述 (2)1.1问题描述 (2)1.2基本要求 (2)1.3测试数据 (2)2.实现分析 (2)3.程序设计 (3)3.1存储结构设计 (3)3.2主要算法设计 (3)3.2.1程序主要函数原型及功能 (3)3.2.2各函数的实现 (4)3.2.3函数模块 (8)3.2.4程序流程图 (8)4.调试报告 (10)4.1调试中的问题 (10)4.2对设计和编码的讨论和分析 (10)5. 程序运行结果 (10)6.经验和体会 (12)6.1感受和体会 (12)6.2对算法改进的想法 (14)7.哈希表和源程序 (14)7.1哈希表 (14)7.2源程序 (15)本科生课程设计成绩评定表 (19)课程设计任务书学生姓名:专业班级:班指导教师:工作单位:计算机科学系题目: 哈希表设计初始条件:针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
假设人名为中国人姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构造,用伪随机探测再散列发处理冲突。
测试用例见题集p166。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)课程设计报告按学校规定格式用A4纸打印(书写),并应包含如下内容:1、问题描述简述题目要解决的问题是什么。
2、设计存储结构设计、主要算法设计(用类C语言或用框图描述)、测试用例设计;3、调试报告调试过程中遇到的问题是如何解决的;对设计和编码的讨论和分析。
4、经验和体会(包括对算法改进的设想)5、附源程序清单和运行结果。
源程序要加注释。
如果题目规定了测试数据,则运行结果要包含这些测试数据和运行输出,6、设计报告、程序不得相互抄袭和拷贝;若有雷同,则所有雷同者成绩均为0分。
时间安排:1、第19周完成。
2、7月1 日14:00到计算中心检查程序、交课程设计报告、源程序(CD盘)。
课程设计报告-哈希表
(此文档为word格式,下载后您可任意编辑修改!) 数据结构课程设计(哈希表的设计)院系专业班级学生姓名学号课程设计日期:2011年6月26日至2011年7 月7 日目录一、问题描述 (3)二、需求分析1、基本要求 (3)2、测试数据 (3)三、概要设计 (3)四、详细设计 (4)五、测试分析 (11)六、课程设计总结 (13)七、附录(源代码) (14)一、问题描述针对自己班级体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
二、需求分析基本要求:假设人名为中国姓名的汉语拼音模式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构造,用链表法处理冲突。
测试数据:输入30个人的姓名拼音,即30个字符串,然后用除留余数法构建哈希表并用链表法处理冲突,最后将结果输出,程序自动计算查找长度的总数和平均查找长度,然后用户可以根据需求进行查找操作。
三、概要设计四、详细设计头文件#include <stdio. 30 *哈希表长度*int sum=0,k=0;typedef struct Node*哈希表结构体*{char key_code[10];*哈希表地址*struct Node *next;}Node;typedef struct mode;}void Hash_Init(HashTable str[0]+str[1]+str[2]; }int Hash_Insert(HashTable 1;}Node* Hash_Search(HashTable NULL;} else if( p;}p = p->next;sum++;}}return NULL;}int Hash_Create(HashTable ");return 1;}int ;i++){printf("%4d",i);printf("%4d",");}return count2;}void Hash_Link()*链表法构造函数*{int key;int i;Node *node;HashTable ",k); *查找总长度*printf("ASL=%d8\n",k); *平均查找长度*printf("请输入要查找的数据:");*输入查找的姓名*scanf("%s",&key);node = Hash_Search(",sum);if(node != NULL)printf("查找成功!");elseprintf("查找不成功!");}void -1;di++){address=((data%P)+di)%;if(status[address]==0){;}int 1;else{for(di=1;di<=-1;di++)*哈希表中元素与查找元素不相等,查找下一元素* {address=((key%P)+di)%;if( di+1;break;}}}if(di>=)return 0;}int main()*主函数*{printf("\t\t\t************************\n");printf("\t\t\t 哈希表设计\n");printf("\n");printf("\t\t\t************************\n");printf("\n");Hash_Link();}五、测试分析测试数据:随机输入的30个人的姓名拼音测试过程:输入30个人的姓名拼音,观察输出结果,并进行查找操作测试结果:主界面:哈希表:六、课程设计总结这次数据结构课程设计持续了两周,在这两周中付出了很多,同样也得到了很多。
哈希表实验报告
数据结构实验报告四——哈希表查找名字(字符串)实验题目:哈希表查找名字(字符串)实验目标:输入一组名字(至少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. 伪随机探测再散列相较于线性探测再散列或二次探测再散能有效的防止二次堆积。
数据结构设计报告--哈希查找与实现
数据结构课程设计报告书班级BX1001专业计算机科学与技术学号101003020139姓名赵冠博课题描述:哈希表的查找与实现分析1、 需求分析:本次课程设计需要实现哈希表的建立和查找,具体内容如下:建立哈希函数,从而根据用户输入的数据元素个数和各元素的值建立哈希表,即数据的添加和存储。
如果输入的元素个数超出规定范围,则打印出错信息,并提示重新输入信息。
哈希表建立好之后,用户可以输入想要查找的值,屏幕显示相应信息。
如果存在此值,屏幕显示该值信息;如果不存在,则显示该值不存在;如果想退出系统,则按提示输入命令。
2、 总体结构设计:1> 一个哈希表结构hashtable ,2>一个main ()主函数(完成数据输入和函数调用)、3>五个功能函数:Initialhash ()//初始化哈希表Printhash ()//输出哈希表的所有元素及其位置Searchhash ()//查找哈希表inserthash ()//查找哈希表deletehash ()//查找哈希表3、 各子模块设计:构成如下图所示:【设计思想】选取某个函数,依该函数按关键字计算元素的存储位置,并按此存放;查找时,由同一个函数对给定值kx 计算地址,将kx 与地址单元中元素关键字进行比较,确定查找是否成功,这就是哈希方法。
哈希方法中使用的转换函数称为Searchhash () Printhash () Initalhash() inserthash () deletehash哈希查找程序main()哈希函数。
程序首先通过插入操作建立哈希表,接着显示数据,然后运用哈希查找找到数据,如没有找到则显示查找错误,找到则显示查找成功。
4、编程实现:【实验程序主要代码】:#define MAXSIZE 12 //哈希表的最大容量,与所采用的哈希函数有关enum BOOL{False,True};enum HAVEORNOT{NULLKEY,HAVEKEY,DELKEY};//哈希表元素的三种状态,没有记录、有记录、有过记录但已被删除typedef struct //定义哈希表的结构{ int elem[MAXSIZE]; //数据元素体HAVEORNOT elemflag[MAXSIZE];//元素状态,没有记录、有记录、有过记录但已被删除 int count; // 哈希表中当前元素的个数}HashTable;typedef struct{ int keynum; // 记录的数据域,只有关键字一项}Record;void InitialHash(HashTable&); // 初始化哈希表void PrintHash(HashTable); // 显示哈希表中的所有元素BOOL SearchHash(HashTable,int,int&); // 在哈希表中查找元素BOOL InsertHash(HashTable&,Record); // 在哈希表中插入元素BOOL DeleteHash(HashTable&,Record); // 在哈希表中删除元素int Hash(int); // 哈希函数void main(){ HashTable H; // 声明哈希表Hchar ch,j='y';int position,n,k;Record R;BOOL temp;InitialHash(H);while(j!='n'){ printf("\n\t 哈希查找 ");printf("\n\t**************************************");printf("\n\t* 1-----建表 *");printf("\n\t* 2-----显示 *");printf("\n\t* 3-----查找 *");printf("\n\t* 4-----插入 *");printf("\n\t* 5-----删除 *");printf("\n\t* 0-----退出 *");printf("\n\t**************************************");printf("\n\n\t请输入菜单号:");scanf(" %c",&ch); // 输入操作选项switch(ch){ case '1':printf("\n请输入元素个数(<10): ");scanf("%d",&n);printf("\n");for( k=0;k<n;k++){ printf("请输入第%3d个整数: ",k+1);scanf("%d",&R.keynum); // 输入要插入的记录temp=InsertHash(H,R);};break;case '2':if(H.count) PrintHash(H); // 哈希表不空else printf("\n散列表为空表!\n");break;case '3':if(!H.count) printf("\n散列表为空表!\n"); // 哈希表空else{ printf("\n请你输入要查找元素(int) :");scanf("%d",&R.keynum); // 输入待查记录的关键字temp=SearchHash(H,R.keynum,position);// temp=True:记录查找成功;temp=False:没有找到待查记录if(temp) printf("\n查找成功该元素位置是 %d\n",position); else printf("\n本散列表没有该元素!\n");}break;case '4':if(H.count==MAXSIZE) // 哈希表已满 { printf("\n散列表已经满!\n");break; }printf("\n请输入要插入元素(int):");scanf("%d",&R.keynum); // 输入要插入的记录 temp=InsertHash(H,R);// temp=True:记录插入成功;temp=False:已存在关键字相同的记录if(temp) printf("\n元素插入成功!\n");else printf("\n元素插入失败,相同元素本散列表已经存在!\n"); break;case '5':printf("\n请你输入要删除元素(int):");scanf("%d",&R.keynum); // 输入要删除记录的关键字temp=DeleteHash(H,R);// temp=True:记录删除成功;temp=False:待删记录不存在if(temp) printf("\n删除成功!\n");else printf("\n删除元素不在散列表中!\n");break;default: j='n';}}printf("\n\t欢迎再次使用本程序,再见!\n");}void InitialHash(HashTable &H) // 哈希表初始化{ int i;H.count=0;for(i=0;i<MAXSIZE;i++) H.elemflag[i]=NULLKEY;}void PrintHash(HashTable H) // 显示哈希表所有元素及其所在位置{ int i;for(i=0;i<MAXSIZE;i++) printf("%-4d",i); // 显示哈希表中记录所在位置printf("\n");for(i=0;i<MAXSIZE;i++) // 显示哈希表中记录值if(H.elemflag[i]==HAVEKEY) printf("%-4d",H.elem[i]);else printf("%4c",' ');printf("\ncount:%d\n",H.count); // 显示哈希表当前记录数}BOOL SearchHash(HashTable H,int k,int &p){ // 在开放定址哈希表H中查找关键字为k的数据元素,若查找成功,以p指示待查//数据元素在表中的位置,并返回True;否则,以p指示插入位置,并返回Falseint p1;p1=p=Hash(k); // 求得哈希地址while(H.elemflag[p]==HAVEKEY&&k!=H.elem[p]) //该位置填有记录并且关键字不相等 { p++; // 冲突处理方法:线性探测再散列if(p>=MAXSIZE) p=p%MAXSIZE; // 循环搜索if(p==p1) return False; // 整个表已搜索完,没有找到待查元素 }if(k==H.elem[p]&&H.elemflag[p]==HAVEKEY) // 查找成功,p指示待查元素位置 return True;else return False; // 查找不成功}BOOL InsertHash(HashTable &H,Record e){ // 查找不成功时插入元素e到开放定址哈希表H中,并返回True,否则返回False int p;if(SearchHash(H,e.keynum,p)) // 表中已有与e有相同关键字的元素return False;else{ H.elemflag[p]=HAVEKEY; // 设置标志为HAVEKEY,表示该位置已有记录H.elem[p]=e.keynum; // 插入记录H.count++; // 哈希表当前长度加一return True;}}BOOL DeleteHash(HashTable &H,Record e){ // 在查找成功时删除待删元素e,并返回True,否则返回Falseint p;if(!SearchHash(H,e.keynum,p)) return False; // 表中不存在待删元素else{ H.elemflag[p]=DELKEY; // 设置标志为DELKEY,表明该元素已被删除 H.count--; // 哈希表当前长度减一return True;}}int Hash(int kn){ return (kn%11); } // 哈希函数:H(key)=key MOD 115、测试结果:【程序运行结果】建表和显示:查找:插入:删除:通过分析输入数据和运行结果,证明程序顺利完成实验内容和要求。
《哈希表》项目实验报告
《哈希表》项目实验报告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,所以在算法上程序构造相对的比较简单。
数据结构课程设计报告——哈希表实现电话号码查询
数据结构课程设计报告一、需求分析1问题描述:根据需要设计出合理的函数,并由此建立相应的表。
要求:1)每个电话用户信息包括(姓名,电话,住址)信息。
2)可以使用姓名与地址查找相应的用户信息。
3)使用表实现。
使用开放定址法解决冲突。
2 基本要求:1)记录每个用户的姓名、地址和电话。
2)从键盘输入,以姓名和地址为关键字分别建立表。
3)用开放地址法解决冲突。
4)分别按姓名和地址查找并显示电话号码。
二、概要设计三、详细设计定义结构表{定义表内的所有成员}[];( x[])关键字转换为数值{求字符数组x每个字符对应的值的绝对值之和,并返回最后结果}( )创建表{创建表,并初始化它}( d) 按姓名插入{以姓名为关键字,调用关键字转换函数将对应的电话号码存储到相应的存储空间。
若该位置已经被存储,则向后移一位(当移到最后一位,就移到头部继续)。
若还有冲突重复上一步。
当所有空间都查过一遍,发现没有空位,则输出“没有存储空间”。
}( d)按地址插入{以地址为关键字,调用关键字转换函数将对应的电话号码存储到相应的存储空间。
若该位置已经被存储,则向后移一位(当移到最后一位,就移到头部继续)。
若还有冲突重复上一步。
当所有空间都查过一遍,发现没有空位,则输出“没有存储空间”。
}( )表插入{输入用户姓名、地址和电话,分别调用按姓名插入和按地址插入函数进行插入。
重复上面的步骤,直到你不想继续或空间已满。
}( )按姓名查找{输入你想要查询的姓名,对它进行转换,再查找。
若该位置不空或求得的关键字所对应的数值与该位置的数值不相等,则向后移一位(当移到最后一位,就移到头部继续)。
若还有冲突重复上一步。
当所有空间都查过一遍,发现没有找到,则输出“不存在”。
若该位置空,则输出“不存在”。
若查找到,则输出电话号码。
}( )按地址查找{输入你想要查询的地址,对它进行转换,再查找。
若该位置不空或求得的关键字所对应的数值与该位置的数值不相等,则向后移一位(当移到最后一位,就移到头部继续)。
哈希表的实验报告
哈希表的实验报告哈希表的实验报告哈希表是一种常见的数据结构,用于存储和查找数据。
在本次实验中,我们将探索哈希表的原理、实现和性能,并通过实验验证其效果。
一、实验目的本次实验的目的是探索哈希表的原理和实现方法,并通过实验测试不同哈希函数和哈希表大小对性能的影响。
二、实验原理哈希表是一种基于哈希函数的数据结构,它将数据存储在数组中,通过哈希函数将数据映射到数组的特定位置。
哈希函数将数据转换为数组的索引,使得数据可以快速存储和查找。
哈希函数的选择很重要,一个好的哈希函数应该具备以下特点:1. 均匀性:哈希函数应该将数据均匀地分布到不同的索引位置,以避免冲突。
2. 高效性:哈希函数应该具有高效的计算速度,以提高哈希表的性能。
3. 低冲突:哈希函数应该尽可能减少冲突的发生,以提高哈希表的查找效率。
三、实验方法1. 实现哈希表:我们首先需要实现一个基本的哈希表数据结构。
哈希表可以使用数组来存储数据,每个数组元素称为一个桶,每个桶可以存储多个数据项。
在实现哈希表时,我们需要考虑如何处理冲突,常见的方法有链地址法和开放地址法。
2. 实现哈希函数:我们需要实现不同的哈希函数,以测试它们的性能。
常见的哈希函数包括除余法、乘法和平方取中法等。
我们可以通过实验比较它们的性能,选择最合适的哈希函数。
3. 测试性能:我们需要设计一系列实验,测试不同哈希函数和哈希表大小对性能的影响。
可以通过插入、查找和删除等操作来评估哈希表的性能。
我们可以记录每个操作的平均时间复杂度和空间占用情况,并绘制图表来展示结果。
四、实验结果与分析通过实验,我们得到了不同哈希函数和哈希表大小下的性能数据。
我们可以观察到不同哈希函数对性能的影响,并选择最优的哈希函数。
同时,我们还可以观察到哈希表大小对性能的影响,选择合适的哈希表大小以平衡性能和空间占用。
五、实验总结本次实验我们深入了解了哈希表的原理和实现方法,并通过实验验证了不同哈希函数和哈希表大小对性能的影响。
实验5 哈希表实验报告
哈希表一、实验目的学会哈希函数的构造方法,处理冲突的机制以及哈希表的查找。
二、实验内容说明以下概念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构造查找表时,可以选择一个适当的装填因子 ,使得平均查找长度限定在某个范围内。
数据结构实验报告(哈希表)
散列表的设计实验报告1、题目:散列表的设计:针对某个集体中人名设计一个散列表,使得平均查找长度不超过R,并完成相应的建表和查表程序。
2、基本要求:假设人名为中国人姓名的汉语拼音形式。
待填入哈希表的人名共30个,取平均查找长度上限为2,哈希函数用除留余数法构造,用伪随机探测再散列法处理冲突。
人名长度不超过20个字符。
可先对过长的人名作折叠处理。
3、设计思想:a.构造哈希函数的方法很多,常用的有(1)直接定址法(2)数字分析法;(3)平方取中法;(4)折叠法;( 5)除留余数法;(6)随机数法;本实验采用的是除留余数法:取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址H(key)=key MOD p,p<=m.b.哈希函数可以减少冲突,但不能避免。
通常用的处理冲突的方法有:(1)开放定址法,这种方法还包含三种形式,一种叫线性探测再散列,一种叫二次探测再散列,另一种叫伪随机探测再散列。
本实验采用的是第三种伪随机探测再散列。
求下一个开放地址的公式为:Hi=(H(k)+di)MOD m (Di=伪随机数序列)c.对哈希表的操作InitNameList() 操作结果:姓名(结构体数组)初始化CreateHashList() 操作结果:建立哈希表FindList() 操作结果:在哈希表中查找Display() 操作结果:显示哈希表4、程序结构图5、流程图6、数据测试7、程序清单#include<iostream>#include<string>using namespace std;#define HASH_LENGTH 50#define M 47#define NAME_NO 30typedef struct{ char *py;int k;}NAME;NAME NameList[HASH_LENGTH]; typedef struct{ char *py;int k;int si;//查找长度}HASH;HASH HashList[HASH_LENGTH]; void InitNameList(){ char *f;int r,s0,i;for (i=0; i<HASH_LENGTH; i++){NameList[i].py = new char[20];NameList[i].py[0] = 0;}strcpy(NameList[0].py, "lintingting"); strcpy(NameList[1].py, "chenxiaoping"); strcpy(NameList[2].py, "jianghaiyan"); strcpy(NameList[3].py, "wangtingting"); strcpy(NameList[4].py, "zhouhuihui"); strcpy(NameList[5].py, "zhuzhenguo"); strcpy(NameList[6].py, "wuqingwen"); strcpy(NameList[7].py, "chenzuopeng"); strcpy(NameList[8].py, "jinlining"); strcpy(NameList[9].py, "zhandakan"); strcpy(NameList[10].py, "linjiajia"); strcpy(NameList[11].py, "huangwenjun"); strcpy(NameList[12].py, "lizhongjing"); strcpy(NameList[13].py, "sushiding"); strcpy(NameList[14].py, "ouyangyaoyao"); strcpy(NameList[15].py, "chenwei");strcpy(NameList[16].py, "linxiaxiao"); strcpy(NameList[17].py, "zhanjie");strcpy(NameList[18].py, "baishujun"); strcpy(NameList[19].py, "gongqiaoqiao"); strcpy(NameList[20].py, "lvhaitao"); strcpy(NameList[21].py, "jiangqingsong"); strcpy(NameList[22].py, "gubaolong"); strcpy(NameList[23].py, "yehuaisong"); strcpy(NameList[24].py, "wangyuqin"); strcpy(NameList[25].py, "xuefeifei"); strcpy(NameList[26].py, "wujianshu"); strcpy(NameList[27].py, "zhanghuajiang"); strcpy(NameList[28].py, "zhengpan"); strcpy(NameList[29].py, "sudongdong");for(i=0;i<NAME_NO;i++){s0=0;f=NameList[i].py;for(r=0;*(f+r)!='\0';r++)s0=*(f+r)+s0;NameList[i].k=s0;}}void CreateHashList(){int i;for(i=0; i<HASH_LENGTH;i++){HashList[i].py=new char[20];HashList[i].py[0] = 0;HashList[i].k=0;HashList[i].si=0;}for(i=0;i<HASH_LENGTH;i++){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 //冲突{while (HashList[d].k!=0){d=(d+NameList[i].k%10+1)%M; //伪随机探测再散列法处理冲突sum=sum+1;};HashList[d].k=NameList[i].k;HashList[d].py=NameList[i].py;HashList[d].si=sum+1;}}}void FindList(){string name;int s0=0,r,sum=1,adr,d;cout<<"请输入人名的拼音:"<<endl;cin>>name;for(r=0;r<20;r++)s0+=name[r];adr=s0%M; //使用哈希函数d=adr;if(HashList[adr].k==s0)cout<<"姓名:"<<HashList[d].py<<endl<<"关键字:"<<s0<<endl<<"查找长度为: 1"<<endl;else if (HashList[adr].k==0)cout<<"无此记录!"<<endl;else{int g=0;while(g==0){d=(d+s0%10+1)%M;sum=sum+1;if(HashList[d].k==0){cout<<"无此记录!"<<endl;g=1;}if(HashList[d].k==s0){cout<<"姓名:"<<HashList[d].py<<endl<<"关键字:"<<s0<<endl<<"查找长度为:"<<sum<<endl;g=1;}};}}void Display(){int i;float average=0;cout<<"\n地址\t关键字\t\t搜索长度\tH(key)\t 姓名\n";for(i=0; i<50; i++){cout<<i<<" ";cout<<"\t"<<HashList[i].k<<" ";cout<<"\t\t"<<HashList[i].si<<" ";cout<<"\t\t"<<(HashList[i].k%M)<<" ";cout<<"\t "<<HashList[i].py<<" ";cout<<"\n";}for(i=0;i<HASH_LENGTH;i++)average+=HashList[i].si;average/=NAME_NO;cout<<"平均查找长度:ASL("<<NAME_NO<<")="<<average<<endl; }int main(){char x;InitNameList(); CreateHashList ();cout<<"d. 显示哈希表"<<endl<<"f. 查找"<<endl<<"任意键退出"<<endl<<"请选择:"<<endl;while(cin>>x){if(x=='d'){Display();cout<<endl;}else if(x=='f'){FindList();cout<<endl;}else break;}for (int i=0; i<HASH_LENGTH; i++){free(NameList[i].py);free(HashList[i].py);}return 0;}。
数据结构课程设计_哈希表实验报告
福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级: 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();void CreateHash1(HashTable* H,Record* a) //建表,以人的为关键字,建立相应的散列表{ int i,p=-1,c,pp;system("cls"); //若哈希地址冲突,进行冲突处理benGetTime();for(i=0;i<NUM_BER;i++){c=0;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。
完整word版,《数据结构》实验五哈希表
实验五查找一、实验目的(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;}四、测试结果(程序运行结果采用截图的方式打印)五、实验体会(包括收获、心得体会、存在的问题及解决问题的方法、建议等)。
数据结构-哈希表设计实验报告
//头文件main.c#include<stdio.h>#include<stdlib.h>struct keyNum* hash[100];struct keyNum* insertHash(struct keyNum*,int);//关键字插入链表int searchHash(struct keyNum*,int m);//查找链表中是否存在值为m的整数void print(struct keyNum*);//打印链表struct keyNum{int key;//关键字struct keyNum *next;};void main(){int i,k,m,n,num,flag,l,j;int a[] = {280,700,603,430,641,907,640};struct keyNum *head = NULL;num = sizeof(a)/sizeof(int);for(i=0;i<sizeof(a)/sizeof(int);i++){k = a[i];m=k%(num+1);//计算得到关键字的哈希值hash[m]=insertHash(hash[m],k);//将关键字k插入到哈希值为m的链表中}printf("采用链地址法得到的哈希表为:\n");for(i=0;i<num+1;i++){printf("第%d行:",i);print(hash[i]);printf("\n");}printf("请输入要查找的整数值:\n");scanf("%d",&n);for(i=0;i<num+1;i++){l=searchHash(hash[i],n);if(l==1){j=i;break;}}if(l==1)printf("整数值%d在哈希表中,位置为链表%d\n",n,j);}struct keyNum * insertHash(struct keyNum*head,int m){struct keyNum *p0,*p1,*p2,*temp;temp=(struct keyNum*)malloc(sizeof(struct keyNum));temp->key=m;p1=head;p0=temp;//要插入的节点(值为m);if(head==NULL)//1,原来的链表为空,插入到head后{head=p0;p0->next=NULL;}else//原来的链表不为空{while((p0->key>p1->key)&&(p1->next!=NULL))//移动到适当位置 {p2=p1;p1=p1->next;}if(p0->key<=p1->key){if(head==p1)head=p0;//2,插入到第一个节点之前else p2->next=p0;//3,插入到p2指向的节点之后p0->next=p1;}else//4,插入到结尾处{p1->next=p0;p0->next=NULL;}}return(head);}int searchHash(struct keyNum*head,int m)//查找链表head中是否存在m {int k=0;struct keyNum*p;p=head;if(head!=NULL)do{if(p->key==m) //存在m{k=1;break;}p=p->next;}while(p!=NULL);return(k);//存在m值则返回1,否则返回0;}void print(struct keyNum*head)//打印链表head {struct keyNum*p;p=head;if(head!=NULL){do{printf(" -> %d ",p->key);p=p->next;}while(p!=NULL);}elseprintf("null");}头文件HashTable.htypedef struct KeyNum{int key;struct KeyNum* next;}keyNum;//插入keyNum* insertHash(keyNum* head,int m){keyNum *p0,*p1,*p2,*temp;temp=(keyNum*)malloc(sizeof(keyNum));temp->key=m;p1=head;p0=temp;//要插入的节点(值为m);if(head==NULL)//1,原来的链表为空,插入到head后{head=p0;p0->next=NULL;}else//原来的链表不为空{while((p0->key>p1->key)&&(p1->next!=NULL))//移动到适当位置 {p2=p1;p1=p1->next;}if(p0->key<=p1->key){if(head==p1)head=p0;//2,插入到第一个节点之前else p2->next=p0;//3,插入到p2指向的节点之后p0->next=p1;}else//4,插入到结尾处{p1->next=p0;p0->next=NULL;}}return(head);}//查找int searchHash(keyNum*head,int m)//查找链表head中是否存在m{int k=0;keyNum*p;p=head;if(head!=NULL)do{if(p->key==m) //存在m{k=1;break;}p=p->next;}while(p!=NULL);return(k);//存在m值则返回1,否则返回0;}void print(keyNum* head)//打印链表head{keyNum*p;p = head;if(head!=NULL){do{printf(" -> %d ",p->key);p=p->next;}while(p!=NULL);}elseprintf("null");}测试程序 Main.c#include<stdio.h>#include<stdlib.h>#define mSize 100 //数组最大个数#include "HashTable.h"void main(){int i,k,m,n,num,l,j;int a[] = {180,750,600,430,541,900,640};keyNum* hash[mSize];keyNum* head = NULL;num = sizeof(a)/sizeof(int);for(i=0;i<num+1;i++)hash[i] = NULL;for(i = 0;i<num;i++){k = a[i];m=k%(num+1);//计算得到关键字的哈希值hash[m] = insertHash(hash[m],k);//将关键字k插入到哈希值为m 的链表中}printf("当前哈希表如下:\n");for(i=0;i<num+1;i++){printf("第%d行:",i);print(hash[i]);printf("\n");}printf("\n");printf("请输入要查找的元素:\n");scanf("%d",&n);for(i=0;i<num+1;i++){l=searchHash(hash[i],n);if(l==1){j=i;break;}}if(l==1)printf("\n整数值%d在哈希表中,位置为链表%d\n",n,j);else printf("\n整数值%d不在哈希表中!\n");}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级:xxxxxx班座号:xxxxxxxxxxxx姓名:xxxxxxx2011年12 月31 日实验题目:哈希表一、要解决的问题针对同班同学信息设计一个通讯录,学生信息有姓名,学号,电话号码等。
以学生姓名为关键字设计哈希表,并完成相应的建表和查表程序。
基本要求:姓名以汉语拼音形式,待填入哈希表的人名约30个,自行设计哈希函数,用线性探测再散列法或链地址法处理冲突;在查找的过程中给出比较的次数。
完成按姓名查询的操作。
运行的环境:Microsoft Visual C++ 6.0二、算法基本思想描述设计一个哈希表(哈希表内的元素为自定义的结构体)用来存放待填入的30个人名,人名为中国姓名的汉语拼音形式,用除留余数法构造哈希函数,用线性探查法解决哈希冲突。
建立哈希表并且将其显示出来。
通过要查找的关键字用哈希函数计算出相应的地址来查找人名。
通过循环语句调用数组中保存的数据来显示哈希表。
三、设计1、数据结构的设计和说明(1)结构体的定义typedef struct //记录{NA name;NA xuehao;NA tel;}Record;{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++;}}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++){c=0;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。
\n",i+1,c); //需要显示冲突次数时输出}printf("\n建表完成!\n此哈希表容量为%d,当前表内存储的记录个数为%d.\n",HASHSIZE,H->count);benGetTime();}(3)查找哈希表void SearchHash1(HashTable* H,int c) //在通讯录里查找姓名关键字,若查找成功,显示信息{int p,pp;NA str;system("cls"); //c用来记录冲突次数,查找成功时显示冲突次数benGetTime();printf("\n请输入要查找记录的姓名:\n");scanf("%s",str);p=Hash1(str);pp=p;while((H->elem[pp]!=NULL)&&(eq(str,H->elem[pp]->name)==-1))pp=collision(p,c);if(H->elem[pp]!=NULL&&eq(str,H->elem[pp]->name)==1){printf("\n查找成功!\n查找过程冲突次数为%d.以下是您需要要查找的信息:\n\n",c);printf("姓名:%s\n学号:%s\n电话号码:%s\n",H->elem[pp]->name,H->elem[pp]->xuehao,H->elem[pp]->tel);}else printf("\n此人不存在,查找不成功!\n");benGetTime();}(4)显示哈希表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;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;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);sum+=*p++;printf("\nsum====================%d",sum);return sum;}int Hash1(NA str){long n;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++){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。