当前位置:
文档之家› 散列法的实验研究 课程设计报告
散列法的实验研究 课程设计报告
else i=c/2+1; } } return (-1); } 用线性再散列法查找,代码实现如下: void SearchHash1(HashTable1 *h,int data) { int d; d=data%HashSize; if(h[d].key==data) printf("数字%d的探查次数为:%d\n",h[d].key,h[d].si); else { do d=(d+1)%HashSize; while(h[d].key!=data && d<HashSize); if(d<HashSize) printf("数字%d的探查次数为:%d\n",h[d].key,h[d].si); else printf("没有查找到你所输入的数\n"); } 用二次探测再散列法查找 void SearchHash2(HashTable2 * h[],int data,int num) { int d; Node *q; d=data%num;
于表长是定值,α与“填入表中的元素个数”成正比,所以,α越大,填入 表中的元素较多,产生冲突的可能性就越大;α越小,填入表中的元素 较少,产生冲突的可能性就越小。实际上,散列表的平均查找长度是装 填因子α的函数,只是不同处理冲突的方法有不同的函数。
(e) 课程总结
(1)收获 通过本次课程设计,使我对计算机语言有了更深一层的了解,也使 我对算法的运用有了更多的体会,对算法和生活的联系也有了更多的体 会。更进一步了解和熟悉了关于哈希表的创建和运用。现在,计算机领 域,他只向我展现了冰山一角,以后我会继续探索。好的算法源于我们 不断的思考,思考源于我们对梦想的追寻。 (2)心得体会 在这次数据结构设计中遇到了很多实际性的问题,在实际设计中才 发现。书本上理论性的东西在实际应用中还是有一定的出入的。所以有 些问题要不断的更正以前的错误思维。通过这次设计,我懂得了学习的 重要性,了解到理论知识与实践结合的重要意义。学会了坚持、耐心和 努力,这将为自己今后的学习和工作打下牢固的基础。通过学习,对专 业知识了解更多,学会如何把自己平时所学的东西应用到实际中。 ----------------------------------------------------------------------------------------参考文献: [1] 李云清,杨庆红. 数据结构(C语言版).北京:人民邮电出版社, 2004. [2] 严蔚敏,吴伟民.数据结构(C语言版).北京:清华大学出版.1997. [3] 苏光奎,李春葆.数据结构导学.北京:清华大学出版.2002. [4] 周海英,马巧梅,靳雁霞.数据结构与算法设计.北京:国防工业出版 社,2007.
typedef struct { Node *link; }HashTable2; typedef struct { int * elem[HashSize]; int count; int size; }HashTable3; (2) 主函数模块 void main() { int data; HashTable1 hash1[HashSize]; HashTable2 * hash2[HashSize]; HashTable3 * ha; ha=(HashTable3 *)malloc(sizeof(HashTable3)); for(int i=0;i<HashSize;i++) ha->elem[i]=NULL; ha->count=0; ha->size=HashSize; int a[MaxSize]; while(1) { printf("\n ┏━━━━━━━━━━━━━━━┓ "); printf("\n ┃ 欢迎使用本系统 ┃ "); printf("\n ┏〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
┓"); printf("\n ┃★ ★ ★ ★ ★ ★散列法的实验研究★ ★ ★ ★ ★ ★┃"); printf("\n ┃ 【1】. 添加数据信息 【2】 数据的输出 ┃"); printf("\n ┃ 【3】. 建立哈希表(线性再散列) ┃"); printf("\n ┃ 【4】. 建立哈希表(二次探测再散列) ┃"); printf("\n ┃ 【5】. 建立哈希表(链地址法) ┃"); printf("\n ┃ 【6】. 线性再散列法查找 ┃"); printf("\n ┃ 【7】. 二次探测再散列法查找 ┃"); printf("\n ┃ 【8】. 链地址法查找 ┃"); printf("\n ┃ 【0】. 退出程序 ┃"); printf("\n ┗〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 ┛"); printf("\n"); printf("\n"); printf("请输入一个任务选项>>>"); int x; scanf("%d",&x); switch(x) { case 1: GetIn (a);break; case 2: GetOut(a);break; case 3: CreateHashTable1(hash1,a,num);break; case 4: CreateHash3(ha,a,num);break; case 5:
q=h[d]->link; while(q->key!=data && q->next!=NULL) q=q->next; if(q->next!=NULL) printf("数字%d的查找次数为:%d\n",q->key,q->next); else printf("没有找到你要查找的那个数\n"); } 用链地址法查找,代码实现如下: void CreateHashTable2(HashTable2 *ht[],int *a,int num)//哈希表链地 址; { int i,d,cnt; Node *s,*q; for(i=0;i<num; i++) { ht[i]=(HashTable2 *)malloc(sizeof(HashTable2)); ht[i]->link=NULL; } for(i=0;i<num;i++) { cnt=1; s=(Node *)malloc(sizeof(Node)); s->key=a[i];s->next=NULL; d=a[i]%num; if(ht[d]->link==NULL) { ht[d]->link=s;
课程设计报告
问题描述:
(1) 散列法中,散列函数构造方法多种多样,同时对于同一散列函数解 决冲突的方法也可以不同。两者是影响查询算法性能的关键因素。 (2) 程序实现几种典型的散列函数构造方法,并观察,不同的解决冲突 方法对查询性能的影响。
a. 需求分析:
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而 直接进行访问的数据结构。对不同的关键字可能得到同一散列地址,即 key1≠key2,而f(key1)=f(key2),这种现象称冲突。具有相同函数值的关 键字对该散列函数来说称做同义词。综上所述,根据散列函数H(key)和 处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间) 上,并以关键字在地址集中的“象”作为记录在表中的存储位置,这种表 便称为散列表,这一映象过程称为散列造表或散列,所得的存储位置称 散列地址。 散列表的查找过程基本上和造表过程相同。一些关键码可通过散列 函数转换的地址直接找到,另一些关键码在散列函数得到的地址上产生 了冲突,需要按处理冲突的方法进行查找。对散列表查找效率的量度, 依然用平均查找长度来衡量。查找过程中,关键码的比较次数,取决于 产生冲突的多少,产生的冲突少,查找效率就高,产生的冲突多,查找 效率就低。因此,影响产生冲突多少的因素,也就是影响查找效率的因 素。该课程设计要求比较几种哈希函数的构造方法和解决冲突的方法对 查询性能的影响。
数据的输出,运行结果如下图:
用线性再散列方法建立哈希表,运行结果如下图:
用二次探测再散列建立哈希表,运行结果如下图:
用线性再散列法查找,运行结果如下图所示:
用二次探测再散列法查找,运行结果如下图:
用链地址法查找,运行结果如下图:
退出程序,运行结果如下图:
对性能的分析:查找过程中,关键码的比较次数,取决于产生冲突 的多少,产生的冲突少,查找效率就高,产生的冲突多,查找效率就 低。因此,影响产生冲突多少的因素,也就是影响查找效率的因素。影 响产生冲突多少有以下三个因素: 1、散列函数是否均匀;2、处理冲 突的方法;3、散列表的装填因子。 散列表的装填因子定义为:α= 填入 表中的元素个数 / 散列表的长度。α是散列表装满程度的标志因子。由
b. 概要设计该程序实现对哈希 Nhomakorabea数的构造方法、处理冲突的方法及在哈希表中
查找数据的功能。 用线性再散列方法建立哈希表,用代码实现为: typedef struct { int key; int si; }HashTable1; void CreateHashTable1(HashTable1 *H,int *a,int num)//哈希表线性探测 在散列; { int i,d,cnt; for(i=0;i<HashSize;i++) { H[i].key=0; H[i].si=0; } for(i=0;i<num;i++) { cnt=1; d=a[i]%HashSize; if(H[d].key==0) { H[d].key=a[i]; H[d].si=cnt; } else { do