哈希表的设计与实现-数据结构与算法课程设计报告
大数据结构课程设计--哈希表实验报告材料
福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级: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。
哈希表课程设计报告
设计题目哈希表查找的设计任务:设哈希表长为20,用除留余数法构造一个哈希函数,以开放定址法中的线性探测再散列法作为解决冲突的方法,编程实现哈希表查找、插入和建立算法。
功能要求:编程实现哈希表查找、插入和建立算法需求分析用除留余数法构造一个哈希函数,以开放定址法中的线性探测再散列法作为解决冲突的方法,编程实现哈希表查找、插入和建立算法概要设计typedef struct{int shuzhi;}hashtable;int hash_function(int shuzhi,int Prime);void CreateHashTable(hashtable ht[],int Prime);int InsertHashTable(hashtable ht[], int shuzhi,int Prime);int SearchHash(hashtable ht[], int shuzhi,int Prime);程序调用关系如下:CreateHashTable SearchHashInsertHashTableSearchHashhash_function详细设计#include <stdio.h>#define Length 20#define SUCCESS 1#define UNSUCCESS 0typedef struct{int shuzhi;}hashtable;int hash_function(int shuzhi,int Prime);void CreateHashTable(hashtable ht[],int Prime);int InsertHashTable(hashtable ht[], int shuzhi,int Prime);int SearchHash(hashtable ht[], int shuzhi,int Prime);int hash_function(int shuzhi,int Prime){return(shuzhi % Prime);}void CreateHashTable(hashtable ht[],int Prime){int hash_table_number = 0;int shuzhi = 0;printf("请输入哈希表中关键字个数,不要超过%d\n", Length);scanf("%d", &hash_table_number);for (int i = 0; i < hash_table_number; i++){printf("请输入哈系表的关键字:\n");scanf("%d", &shuzhi);InsertHashTable(ht, shuzhi,Prime);}}int InsertHashTable(hashtable ht[], int shuzhi,int Prime){int result = 0;result = SearchHash(ht, shuzhi,Prime);if (ht[result].shuzhi == 0){ht[result].shuzhi = shuzhi;printf("插入数据成功!\n");return SUCCESS;}else{printf("插入数据失败\n");return UNSUCCESS;}}int SearchHash(hashtable ht[], int shuzhi,int Prime){int hash_address = 0;int i = 0;hash_address = hash_function(shuzhi,Prime); //求hash地址while ((shuzhi != ht[hash_address].shuzhi) && (ht[hash_address].shuzhi!=NULL) && (i < Length)){i++;hash_address = (hash_address + 1) % Prime; //线性探查记录的插入位置}if (i >= Length){printf("哈希表已满\n");return UNSUCCESS;else{return hash_address;}}void Print(hashtable ht[]){printf("哈希表地址存储数值\n");for(int i=0;i<Length;i++){if(ht[i].shuzhi!=NULL)printf("%8d%8d\n",i,ht[i].shuzhi);else continue;}}int main(){hashtable ht[Length];int shuzhi = 0;int Prime;printf("-------------欢迎哈希表系统-----------\n");printf("输入哈希函数除留余数法中的除数:");scanf("%d",&Prime);for (int i = 0; i < Length; i++){ht[i].shuzhi = NULL;}CreateHashTable(ht,Prime);printf("输入要查找元素的关键字:\n");scanf("%d", &shuzhi);i = SearchHash(ht, shuzhi,Prime);if (ht[i].shuzhi == shuzhi){printf("表中存关键字为%d的元素的地址是%d:\n", shuzhi,i); }else{printf("没找到\n");}printf("输出哈希表:\n");Print(ht);return 0;}调试分析1、hash_address = (hash_address + 1) % Prime; //线性探查记录的插入位置一开始写成了hash_address = (hash_address + i) % Prime; //线性探查记录的插入位置,我用笔在纸上算了2遍,才发现了错误2、printf("%8d%8d\n",i,ht[i].shuzhi);一开始没想到这个方法,弄得输出界面很难看,后来才想到的用户手册(1)演示程序的运行环境为Windows Xp系统,Microsoft Visual Studio 6.0中的Microsoft Visual C++ 6.0中运行。
《数据结构》课程设计-哈希表设计
目录课程设计任务书 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个人的姓名拼音,观察输出结果,并进行查找操作测试结果:主界面:哈希表:六、课程设计总结这次数据结构课程设计持续了两周,在这两周中付出了很多,同样也得到了很多。
数据结构课程设计报告——哈希表实现电话号码查询
数据结构课程设计报告一、需求分析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表插入{输入用户姓名、地址和电话,分别调用按姓名插入和按地址插入函数进行插入。
数据结构课程设计哈希表实验报告
数据结构课程设计哈希表实验报告数据结构课程设计哈希表实验报告福建工程学院课程设计课程:算法与数据结构题目:哈希表专业:网络工程班级: 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) //冲突处理函数,采用二次探测再散列法解决冲突{。
数据结构设计报告--哈希查找与实现
数据结构课程设计报告书班级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、题目:散列表的设计:针对某个集体中人名设计一个散列表,使得平均查找长度不超过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。
数据结构与算法课程设计报告
数据结构与算法课程设计报告摘要:本文是对数据结构与算法课程设计的报告,主要介绍了课程设计的目标、设计思路和实现过程。
通过该课程设计,学生能够加深对数据结构和算法的理解,提高编程能力和问题解决能力。
本文详细介绍了课程设计的背景和需求分析,然后提出了设计思路和方案,并对具体实现进行了详细的说明和分析。
最后,总结了课程设计的收获和不足之处,并提出了改进的建议。
关键词:数据结构,算法,课程设计,设计思路,实现过程第一部分:引言1.1 背景数据结构和算法是计算机科学中非常重要的基础知识,对于软件开发和问题解决都起着至关重要的作用。
因此,数据结构与算法课程设计作为计算机科学专业的核心课程之一,对于学生的学习和培养具有重要意义。
1.2 需求分析本课程设计的目标是通过实际的项目开发,让学生深入理解数据结构和算法的原理,并能够灵活运用于实际问题的解决中。
具体需求如下:学生能够选择合适的数据结构和算法来解决实际问题。
学生能够设计和实现基于数据结构和算法的算法。
学生能够分析和评估算法的效率和性能。
第二部分:设计思路与方案2.1 设计思路本课程设计的设计思路是通过实际的项目开发来实现学生对数据结构和算法的深入理解。
项目的选择应该能够涵盖多种数据结构和算法的应用,并且能够充分体现算法的效率和性能优化。
2.2 设计方案基于上述设计思路,我们选择了一个图论相关的项目作为课程设计的实践项目。
该项目涉及到图的表示和遍历、最短路径算法以及最小生成树算法等多个知识点。
学生需要设计和实现一个图的数据结构,并能够基于该数据结构实现相关的算法。
第三部分:具体实现与分析3.1 图的数据结构设计与实现为了表示一个图,我们选择了邻接表作为数据结构的实现方式。
邻接表能够有效地表示图的结构,并且支持图的遍历和算法的实现。
通过链表的方式,每个节点可以存储与其相邻的节点信息。
此外,我们还设计了相关的操作函数,包括添加节点、添加边、删除节点和删除边等。
3.2 最短路径算法实现与分析在设计最短路径算法时,我们采用了Dijkstra算法作为实现的基础。
数据结构哈希表设计
数据结构哈希表设计1.引言哈希表(Hash Table)是一种常用的数据结构,用于快速存储和检索数据。
它通过将键(Key)映射到值(Value)来实现高效的数据存储和查找。
本文将介绍哈希表的设计原理和实现方法,以及一些常见的应用场景。
2.哈希函数的选择哈希函数是实现哈希表的关键,它将键映射到哈希值。
一个好的哈希函数应当具有以下特点:●均匀性:对于任意的输入,哈希函数应该能够将其均匀地映射到哈希表的各个位置,避免产生过多的冲突。
●高效性:哈希函数应当能够在常数时间内计算出哈希值,避免影响哈希表的性能。
●低冲突性:哈希函数应当能够尽可能少的冲突,即不同的键经过哈希函数计算得到相同的哈希值的概率应当很低。
3.冲突解决方法由于哈希函数的有限性,不同的键可能会产生相同的哈希值,这种情况称为冲突。
常见的冲突解决方法有以下几种:●链地质法(Chning):将哈希表的每个位置引入链表,当多个键映射到相同的位置时,将它们存储在链表中。
●开放寻址法(Open Addressing):当发生冲突时,通过一定的方法在哈希表中寻找下一个可用的位置,直到找到一个空位置或者遍历完整个哈希表。
●再哈希法(Rehashing):当发生冲突时,通过应用另一个哈希函数来计算出一个新的哈希值,以此来解决冲突。
4.哈希表的操作哈希表支持以下几种操作:●插入(Insert):将一个键值对插入到哈希表中。
●删除(Delete):从哈希表中删除指定的键值对。
●查找(Search):根据给定的键,在哈希表中查找对应的值。
●更新(Update):根据给定的键,更新哈希表中对应的值。
5.哈希表的应用哈希表广泛应用于各种场景,例如:●缓存:哈希表可以用于实现高效的缓存系统,根据请求的键值对快速查找到对应的数据。
●字典:哈希表可以被用作实现字典,将单词与其定义相关联。
●数据库索引:哈希表可以用于构建数据库的索引,提高数据的检索性能。
6.总结哈希表是一种高效的数据结构,通过将键映射到值来实现快速的数据存储和检索。
(完整word版)哈希表《数据结构》课程设计
数学与计算机学院课程设计说明书课程名称: 数据结构-课程设计课程代码: 8404181题目:哈希表的设计与实现年级/专业/班: 2009级软件工程3班学生姓名:张加发学号:312009*********开始时间:2011 年06 月20 日完成时间:2011 年06 月29 日课程设计成绩:学习态度及平时成绩(30)技术水平与实际能力(20)创新(5)说明书撰写质量(45)总分(100)指导教师签名: 年月日数据结构课程设计任务书学院名称: 数学与计算机学院课程代码:8404181专业:软件工程年级:2009级一、设计题目哈希表的设计与实现二、主要内容设计哈希表实现电话号码查找系统,要求如下:1)设每个记录有下列数据项:电话号码、用户名、地址;2)从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表(要求设计两种以上不同的散列函数);3)采用两种以上的方法解决冲突;4)查找并显示给定电话号码的记录;5)查找并显示给定用户名的记录。
三、具体要求及应提交的材料1.每个同学以自己的学号和姓名建一个文件夹,如:“312009*********张三”。
里面应包括:学生按照课程设计的具体要求所开发的所有源程序(应该放到一个文件夹中)、任务书和课程设计说明书的电子文档。
2.打印的课程设计说明书(注意:在封面后夹入打印的“任务书”以后再装订)。
四、主要技术路线提示法、除留余数法等,解决冲突的方法也较多,常用:开放定址法、链地址法等。
五、进度安排共计两周时间,建议进度安排如下:选题,应该在上机实验之前完成需求分析、概要设计可分配4学时完成详细设计可分配4学时调试和分析可分配10学时.2学时的机动,可用于答辩及按教师要求修改课程设计说明书。
注:只用课内上机时间一般不能完成设计任务,所以需要学生自行安排时间做补充.六、推荐参考资料[1]苏仕华等编著,数据结构课程设计,机械工业出版社,2007[2]严蔚敏等编著,数据结构(C语言版),清华大学出版社,2003[3]严蔚敏等编著,数据结构题集(C语言版),清华大学出版社,2003指导教师签名日期年月日系主任审核日期年月日摘要分析了对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的应用,对现实复杂问题的分析建模和解决方法!分析了针对系统的需求所要执行的解决方法的可行性,正确性.完成系统前需要进行问题描述、系统分析、设计建模、代码实现、调试修改,结果分析。
《哈希表》课程设计报告
《哈希表》课程设计报告数据结构散列表(哈希表)课程设计报告及源代码《哈希表的操作》设计报告一目的通过此次课程设计,让学生充分掌握对哈希表的有关操作,例如除留余数法的运用,处理冲突的三个办法:线性探测再散列,二次探测再散列,连地址法等。
加深学生对于哈希表这种独特存储方式(区别于线性存储和链式存储)的理解,和几种算法之间的优越性的体会。
二需求分析1、功能需求①.用户能够自定义输入单词,存入哈希表里;②.用户能够对当前哈希表进行管理。
操作内容包括:查看当前哈希表、搜索某个单词、插入任意单词、删除表中某个单词、查看当前表的平均搜索长度、置空当前哈希表。
③.程序有良好的交互界面,有操作提示和出错提示,方便用户使用和进出入程序。
2、程序约束①.哈希表的散列方法为除留余数法,处理冲突的办法为线性探测在散列。
②.使用C/C++语言编写,程序模块化设计。
三概要设计1、模块设计程序分为主程序模块和哈希表类定义模块,主程序存放在main.app中,哈希表类存放在HashTable.h头文件中。
①.主程序模块用于数据和DOS用户界面的初始化,主函数mai()内部定义子函数function(),调用哈希表类中的各个功能函数。
②.哈希表类定义Calculate(string s) 单词key值计算函数,类友元形参s传送输入的单词。
由于单词为string型,不方便直接拿来参与取余数计算,故用计算函数求出一个key来,同时可以减少冲突(字母相同的单词key有可能不同)。
FindPos(int key,string value) 地址查找函数,类成员key传送计算出的单词的关键值,value传送输入的单词,下同。
此函数为查找、插入、删除等函数提供地址搜索服务。
Search(int key,string value) 查找函数,类成员 Insert(string value) 插入函数,类成员 Remove(int key,string value) 删除函数,类成员 makeEmpty() 置空哈希表函数,类成员感谢您的阅读,祝您生活愉快。
哈希表实现通讯录-数据结构与算法课程设计报告
合肥学院计算机科学与技术系课程设计报告2009~2010学年第二学期课程数据结构与算法课程设计名称哈希表实现通讯录题目:(哈希表的设计与实现的问题)设计哈希表实现电话号码查询系统。
设计程序完成以下要求:(1)设每个记录有下列数据项:电话号码、用户名、地址;(2)从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;(3)采用再哈希法解决冲突;(4)查找并显示给定电话号码的记录;(5)查找并显示给定用户的记录。
一、问题分析和任务定义此程序需要完成如下要求:设计哈希表实现电话号码查询系统。
实现本程序需要解决以下几个问题:(1)设计结点使该结点包括电话号码、用户名、地址。
(2)利用再哈希法解决冲突。
(3)分别以电话号码和用户名为关键字建立哈希表。
(4)实现查找并显示给定电话号码的记录。
(5)查找并显示给定用户的记录。
本问题的关键和难点在于如何解决散列的问题。
由于结点的个数无法的知,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题。
所以采用链地址法散列算法。
采用拉链法,当出现同义词冲突时,使用链表结构把同义词链接在一起,即同义词的存储地址不是散列表中其他的空地址。
首先,解决的是定义链表结点,在拉链法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成.name[8] 、num[11]和address[20]都是char浮点型,输入输出都只能是浮点型的。
采用拉链法,其中的所有同义词构成一个单链表,再由一个表头结点指向这个单链表的第一个结点。
这些表头结点组成一个一维数组,即哈希表。
数组元素的下标对应由散列函数求出的散列地址。
其次,设计散列函数,本程序需要设计两个散列函数才能解决问题,程序需要分别为以电话号码和用户名为关键字建立哈希表。
所以要分别以用户名、号码为关键字建立两个散列函数,对于以号码为关键字的散列函数,是将十一个数字全部相加,然后对20求余。
哈希表的设计与实现课程设计报告
一: 需求分析 (2)三: 详细设计(含代码分析) (4)1. 程序描述: (4)2 具体步骤 (4)四调试分析和测试结果 (7)五,总结 (10)六. 参考文献; (11)七. 致谢 (11)八.附录 (11): 需求分析问题描述:设计哈希表实现电话号码查询系统。
基本要求1、设每个记录有下列数据项:电话号码、用户名、地址2、从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;3、采用再哈希法解决冲突;4、查找并显示给定电话号码的记录;5、查找并显示给定用户名的记录。
6、在哈希函数确定的前提下,尝试各种不同类型处理冲突的方法(至少两种),考察平均查找长度的变化。
概要设计进入主函数,用户输入1或者2,进入分支选择结构:选1:以链式方法建立哈希表, 选2: 以再哈希的方法建立哈希表, 然后用户输入用户信息, 分别以上述确定的方法分别以用户名为检索以及以以电话号码为检索将用户信息添加到哈希表,. 当添加一定量的用户信息后, 用户接着输入用户名或者电话号码分别以用户名或者电话号码的方式从以用户名或电话号码为检索的哈希表查找用户信息. 程序用链表的方式存储信息以及构造哈希表。
具体流程图如下所示程序结束详细设计(含代码分析)1. 程序描述 :本程序以要求使用哈希表为工具快速快速查询学生信息,学生信息包括电话号 码、用户名、地址;用结构体存储struct node{ string phone; //string name; //string address;//node *next; //};2具体步骤1. 要求主要用在哈希法解决冲突, 并且至少尝试用两种方法解决冲突, 定义两 个指针数组存储信息 node *infor_phone[MAX]; node *infor_name[MAX]; 前者以电话号码为关键字检索哈希表中的信息, 后者以姓名为关键字检索哈希表中的 信息 用链式法和再哈希法解决冲突:int hash(string key) //{ //int result=1,cur=0,i; if(key.size()<=4) i=key.size()-1;else i=4;for(;i>=0;i--){ cur=key[i]-'0'; result=result*9+cur;}result%=(MOD); return result;}2. 得到输入信息的哈希码以后, 将相应的信息插入对应的地址, 若产生冲突, 则 循环到这个地址的最后一个节点, 然后再将节点插入到这个位置, 电话号码 姓名 地址 链接下一个地址的指以姓名或者电话号码的前四位运算结果作为哈 希码这样就避免了冲突, 在查找的时候便可直接找到这个地址然后快速的查找到信息:void add_infor_phone(string phone,string name,string address){int value=hash(phone);node *infor=build_infor(phone,name,address);if(infor_phone[value]==NULL)infor_phone[value]=infor;else{node *cur=infor_phone[value];while(cur->next)cur=cur->next;cur->next=infor;}}3. 再哈希法也是解决冲突的常见方法,当同义词产生地址冲突时计算另一个哈希函数地址,知道冲突不再发生,这种方法不易产生聚义,但是增加了计算时间:int hash_agin(int numble,int key) // 将关键字的前四位数经过计算的结果{ // 模上一个定义的数然后返回的数字为return numble%key; // 哈希码}int create(string key){int result=1,cur=0,i;if(key.size()<=4)i=key.size()-1;elsei=4;for(;i>=0;i--){ cur=key[i]-'0';result=result*9+cur;}return result;}4. 同样用链表为储存信息的数据结构,当产生冲突时,将模数减去一然后再寻找地址直到不再产生冲突:void add_infors(string phone,string name,string address){int numble_phone=create(phone),key=MOD,pos_phone,pos_name;while(infor_phone[pos_phone=hash_agin(numble_phone,key)]!=NULL) key--; key=MOD;int numble_name=create(name);while(infor_name[pos_name=hash_agin(numble_name,key)]!=NULL) key--; node *inforphone=new node;node *inforname=new node; inforphone->name=inforname->name=name; inforphone->phone=inforname->phone=phone;inforphone->address=inforname->address=address;inforphone->next=inforname->next=NULL; infor_phone[pos_phone]=inforphone; infor_name[pos_name]=inforname;5 . 帮主函数bool usersayyes() ,返回一个bool 值,要求用户输入一个正确的选项,减少程序因错误输入而出现的问题:bool usersayyes(){string sig;bool continu=true;cout<<" 请输入(N/n) 或(Y/y),(N/n) 代表退出,(Y/y) 代表继续:";while(cin>>sig&&(sig!="Y"&&sig!="y")&&(sig!="N"&&sig!="n")) cout<<" 输入错误, 请重新输入!"<<endl;return sig=="Y"||sig=="y";}四调试分析和测试结果1. 用链式法将用户信息添加到哈希表:2. 以姓名为关键字检索用户信息3. 当哈希表中不存在此项记录时4.再哈希法将用户信息添加到哈希表:5.以姓名为检索在哈希表中查找用户信息6. 以电话为检索在哈希表中查询信息使用哈希表能在较短的时间内查找出数据,程序的结果基本和理论相符合。
哈希表设计-数据结构课程设计
输出超找结果
printf("\n 姓名:%s 关键字:%d 查找长度为: 1\n",HashTable[adr].py,s);
else if (HashTable[adr].m==0)
printf("没有想要查找的人!\n");
else
{
while(1)
{
adr=(adr+d[j++])%HASH_LEN;//伪随机探测再散列法处理冲突
取读者周围较熟悉的 30 个人的姓名。 4. 实现提示
如果随机数自行构造,则应首先调整好随机函数,使其分布均匀。人名的长度均不超 过 19 个字符(最长的人名如:庄双双(Zhuang Shuangshuang))。字符的取码方法可直接利 用 C 语言中的 toascii 函数,并可先对过长的人名先作折叠处理。
四、调试分析
编译环境为 CodeBlocks。
山东科技大学学生课程设计
山东科技大学学生课程设计
山东科技大学学生课程设计
int si; //查找长度
}HASH;
HASH HashTable[HASH_LEN];
//全局定义哈希表
int d[30],i,j; //全局定义随机数,循环用的 i、j
void InitNameTable() {//姓名表的初始化
NameTable[0].py="caowukui"; NameTable[1].py="langzhijie"; NameTable[2].py="dongshuliang"; NameTable[3].py="qiuhouyang"; NameTable[4].py="zhangxu"; NameTable[5].py="duhuan"; NameTable[6].py="fanqing"; NameTable[7].py="songxiaofei"; NameTable[8].py="dutongtong"; NameTable[9].py="sunhaohao"; NameTable[10].py="shanjianfeng"; NameTable[11].py="wangbaoshan"; NameTable[12].py="houfeng"; NameTable[13].py="hujiaming"; NameTable[14].py="jiangkaiqiang"; NameTable[15].py="xuyang"; NameTable[16].py="lvdelu"; NameTable[17].py="shenjinfeng"; NameTable[18].py="xuhui"; NameTable[19].py="hanle"; NameTable[20].py="xunwenwen"; NameTable[21].py="chenhongcong"; NameTable[22].py="zhangyanyan"; NameTable[23].py="nieyanshun"; NameTable[24].py="haopengcheng"; NameTable[25].py="yuhaiyuan"; NameTable[26].py="shuxiang"; NameTable[27].py="sunyingjie"; NameTable[28].py="wangbo"; NameTable[29].py="zhaoqing"; NameTable[30].py="zhangshengqian"; for (i=0;i<NAME_LEN;i++) //将字符串的各个字符所对应的 ASCII 码相加,所得的整数做 为哈希表的关键字
哈希表设计与实现数据结构课程设计
课程名称:数据结构XXXXXXXX本科学生课程设计(论文)题目哈希表的设计与实现姓名 XXX学号 XXXXXXXXXXXX学部计算机科学与技术专业、年级计算机科学与技术大二指导教师 XX2010 年 11月 28日摘要随着信息技术的发展,关于各种程序中的数据结构也是层出不穷,对于项目某一方面的计算或者是某一方面的研究,出现了专门的数据结构,哈希表就是其中之一,哈希表作为另类的一种数据结构,其作用也是区别于其它同类的数据结构的,它是由两部分组成的:键(key)和值,通过键可以迅速的查找到你需要的值。
常见的构造哈希函数的方法有直接定址法除留余数法平方取中法数字分析法等。
一般创建哈希表时可能会出现很多的冲突,常用的处理冲突的方法为开放定址法再哈希法链地址法建立一个公共溢出区。
关键词: 数据结构;哈希表;键(key);目录第1章前言与系统实现 ____________________________________________ 4 1.1前言__________________________________________________________ 4 1.2系统实现______________________________________________________ 51.2.1 开发环境_________________________________________________ 51.2.2 Visual C++环境的安装_____________________________________ 5 第2章系统功能分析_______________________________________________ 6 2.1 系统功能需求分析 ____________________________________________ 6 2.2 任务定义 ____________________________________________________ 6 第3章总体设计___________________________________________________ 7 3.1系统数据结构__________________________________________________ 7 3.2主要算法流程图________________________________________________ 83.2.1 以姓名为关键字的CreateHashList()函数流程图________________ 83.2.2 哈希表查找算法流程图______________________________________ 93.2.3主程序流程图_____________________________________________ 10 第4章详细设计和编码____________________________________________ 114.1节点的建立___________________________________________________ 11 4.2 对哈希函数的定义 ___________________________________________ 11 4.3 创建哈希表算法、代码如下所示: ________________________________ 124.3.1 算法_____________________________________________________ 124.3.2代码_____________________________________________________ 12 4.4哈希查找_____________________________________________________ 13 4.5显示哈希表___________________________________________________ 16 4.6主菜单设计___________________________________________________ 18 4.7 主函数设计 __________________________________________________ 18 第5章程序运行测试_______________________________________________ 215.1程序主界面___________________________________________________ 21 5.2哈希表初始化_________________________________________________ 21 5.3按姓名查找记录_______________________________________________ 23 5.4显示哈希表全部记录___________________________________________ 24 总结______________________________________________________________ 25 参考文献__________________________________________________________ 26第1章前言与系统实现1.1前言在信息化时代的今天,计算机技术已经是发展到一个很可观的地步了,特别是面向窗口的操作系统的出现,使得程序设计更加的容易了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
合肥学院计算机科学与技术系课程设计报告2009 ~2010 学年第二学期课程数据结构与算法课程设计名称哈希表的设计与实现学生姓名王东东学号0804012030专业班级08计本(2)指导教师王昆仑、李贯虹2010 年5 月课程设计目的“数据结构与算法课程设计”是计算机科学与技术专业学生的集中实践性环节之一,是学习“数据结构与算法”理论和实验课程后进行的一次全面的综合练习。
其目的是要达到理论与实际应用相结合,提高学生组织数据及编写程序的能力,使学生能够根据问题要求和数据对象的特性,学会数据组织的方法,把现实世界中的实际问题在计算机内部表示出来并用软件解决问题,培养良好的程序设计技能。
一、问题分析和任务定义1、问题分析要完成如下要求:设计哈希表实现电话号码查询系统。
实现本程序需要解决以下几个问题:(1)如何定义一个包括电话号码、用户名、地址的节点。
(2)如何以电话号码和用户名为关键字建立哈希表。
(3)用什么方法解决冲突。
(4)如何查找并显示给定电话号码的记录。
(5)如何查找并显示给定用户名的记录。
2 任务定义1、由问题分析知,本设计要求分别以电话号码和用户名为关键字建立哈希表,z在此基础上实现查找功能。
本实验是要我们分析怎么样很好的解决散列问题,从而建立一比较合理的哈希表。
由于长度无法确定,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题。
所以采用链地址法散列算法。
采用链地址法,当出现同义词冲突时,可以使用链表结构把同义词链接在一起,即同义词的存储地址不是散列表中其他的空地址。
根据问题分析,我们可以定义有3个域的节点,这三个域分别为电话号码char num[30],姓名char name[30],地址char address[30]。
这种类型的每个节点对应链表中的每个节点,其中电话号码和姓名可分别作关键字实现哈希表的创建。
二、数据结构的选择和概要设计1、数据结构的选择数据结构:散列结构。
散列结构是使用散列函数建立数据结点关键词与存储地址之间的对应关系,并提供多种当数据结点存储地址发生“冲突”时的处理方法而建立的一种数据结构。
散列结构基本思想,是以所需存储的结点中的关键词作为自变量,通过某种确定的函数H(称作散列函数或者哈希函数)进行计算,把求出的函数值作为该结点的存储地址,并将该结点或结点地址的关键字存储在这个地址中。
散列结构法(简称散列法)通过在结点的存储地址和关键字之间建立某种确定的函数关系H,使得每个结点(或关键字)都有一个唯一的存储地址相对应。
当需要查找某一指定关键词的结点时,可以很方便地根据待查关键字K计算出对应的“映像”H(K),即结点的存储地址。
从而一次存取便能得到待查结点,不再需要进行若干次的比较运算,而可以通过关键词直接计算出该结点的所在位置。
2、概要设计(1)、哈希表的定义结点的数据类型:struct node //定义姓名地址电话号码{char name[30];char address[30];char num[30];node * next;}; ElemNode;(2)、哈希地址的计算以姓名为关键字的哈希地址计算:从取得的姓名第二个字母开始,取ASCII码累加,对30求余得所求哈希地址以电话号码为关键字的哈希地址计算:从号码第二位开始,将所有号码累加之后对30求模得哈希地址(3)、拉链法链地址法:在散表结构存放在指针指向的单元中。
链地址法在解决冲突时,使用链表结构把同义词链接在一起,即同义词的存储地址不是散列表中其他的空地址。
采用C语言定义如下:#define Max_length 100Typedef struct{int key;ElemType data;ElemNode *next;}ElemNode;Typedef struct{ElemNode *first;}ElemHeader,HashTable[Max_length];所有的同义词构成一个单链表,再由一个表头节点指向这个单链表的第一个节点。
这些镖头节点组成一个一维数组,即散列表。
数组元素的下标对应由散列函数求出的散列地址。
拉链法处理冲突的散列表结构158(4)链地址法查找结点的算法思想a、根据查找节点的关键字算出哈希地址b、在散列地址所指向的单链表中依次寻找节点c、如果找到,输出节点的信息;否则提示没有找到三、详细设计和编码主流程图。
以号码为关键字的Hash()函数流程图以姓名为关键字的Hash()函数流程图添加结点信息流程图:编码1、建立节点struct node //定义姓名地址电话号码{char name[30];char address[30];char num[30];node * next;};typedef node* pnode; //声明了已有数据类型的两个指针变量typedef node* mingzi;node **phone;node **nam;2、定义哈希函数这里我们需要定义两个哈希函数,一个以电话号码为关键字,另一个以姓名ASCII之和求模之后的值为关键字。
主要方法为将电话号码从第二位开始逐一累加并将所得结果对30求模得哈希地址;第二种则是将姓名字符进行强制类型转换之后得ASCII码相加对30求模得哈希地址。
=============================求哈希地址源代码========================== void hash(char num[30]) //哈希函数//将运算的结果所得的余数作为节点的存储地址{int i = 1;key=(int)num[0];while(num[i]!=NULL){key+=(int)num[i];i++;}key=key%30;}void hash2(char name[30]) //哈希函数//将运算的结果所得的余数作为节点的存储地址{int i = 1;key2=(int)name[0];while(name[i]!=NULL){key2+=(int)name[i];i++;}key2=key2%30;}=====================================================================(3)、添加节点接下来就是每个节点的建立,添加结点,利用链地址法解决冲突。
建立结点应包括动态申请内存空间。
向结点中输入信息。
同时将结点中的next指针等于NULL。
添加结点,首先需要利用哈希函数计算出地址即关键字,然后将所得数据插入到链表中。
===========================动态申请内存空间============================ void create_phone() //新建节点{int i;phone=new pnode[30];for(i=0;i<30;i++){phone[i]=new node;phone[i]->next=NULL;}}void create2_num() //新建节点{int i;nam=new mingzi[30];for(i=0;i<30;i++){nam[i]=new node;nam[i]->next=NULL;}}====================================================================================================添加节点=============================== int apend() //添加节点{node *newphone;node *newname;newphone=input();newname=newphone;newphone->next=NULL;newname->next=NULL;hash(newphone->num); //先计算号码的keyhash2(newname->name); //姓名的key2newphone->next = phone[key]->next;//把该key的号码链接到原来的号码的后一节点上phone[key]->next=newphone;newname->next = nam[key2]->next; //把该key的姓名链接到原来的号码的后一节点上nam[key2]->next=newname;return 0;}=====================================================================(4)、查找节点===================================================================== void find_num(char num[30]) //按号码查找用户信息{hash(num);node *q=phone[key]->next;while(q!= NULL){if(strcmp(num,q->num)==0)break;q=q->next;}if(q)cout<<q->name<<"_" <<q->address<<"_"<<q->num<<endl;else cout<<"无此记录"<<endl;}void find2_nam(char name[30]) //按姓名查找用户信息{hash2(name);node *q=nam[key2]->next;while(q!= NULL){if(strcmp(name,q->name)==0)break;q=q->next;}if(q)cout<<q->name<<"_" <<q->address<<"_"<<q->num<<endl;else cout<<"无此记录"<<endl;}=====================================================================(5)输出哈希表===================================================================== void list_num() //以号码为关键字显示列表{int i;node *p;for(i=0;i<30;i++){p=phone[i]->next;while(p){cout<<p->name<<'_'<<p->address<<'_'<<p->num<<endl;p=p->next;}}}void list2_nam() //以姓名为关键字显示列表{int i;node *p;for(i=0;i<30;i++){p=nam[i]->next;while(p){cout<<p->name<<'_'<<p->address<<'_'<<p->num<<endl;p=p->next;}}}=====================================================================(6)主函数main()四、上机调试1、在调试的时候,出现了无法查找姓名或者电话号码相同的用户的信息当查找姓名相同或者号码相同的用户时,就会出现死循环原先代码如下===================================部分代码=================================== while(q!= NULL){if(strcmp(num,q->num)==0)break;q=q->next;}if(q)cout<<q->name<<"_" <<q->address<<"_"<<q->num<<endl;else cout<<"无此记录"<<endl;}这个子函数只能查找一个符合条件的节点,查找到一个之后就跳出循环了,后经指导老师指出,改为===================================部分代码=================================== int flag;hash(num);node *q=phone[key]->next;while(q!= NULL){if(strcmp(num,q->num)==0){cout<<q->name<<"_" <<q->address<<"_"<<q->num<<endl;flag=1;}q=q->next;}if(flag==0) cout<<"无此记录"<<endl;}=============================================================================== 先前出现问题是因为break语句结束语句指能查找一个节点,改进之后可以实现功能2、文件的操作在这个程序中没有能成功实现,故在最后阶段,删除了这一功能。