采用链地址法处理冲突构造哈希表
来源:互联网 发布:网络回合制游戏 编辑:程序博客网 时间:2024/05/18 00:25
原文链接:
http://www.cnblogs.com/lpshou/archive/2012/05/08/2490191.html
原作者:lpshou
1、背景引入
(1)线性表和树等线性结构中,记录在结构中的相对位置是随机的,和记录的关键字之间不存在确定的关系,因此,在结构中查找记录时需要进行一系列和关键字的比较。理想的情况是希望不经过任何比较,一次存取便能够取到所查找的记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字和结构中一个唯一的存储位置相对应。因而在查找时,只要根据这个对应关系f找到给定值K的像f(K)。若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上,因此,不需要进行比较便可以直接取得所查记录。在此,我们称这个对应关系f为哈希函数,按照这个思想建立的表为哈希表。
哈希函数的构造方法很多,常用的有直接定址法、数字分析法、平方取中法、折叠法、除留余数法、随机数法等,,这里我选择了除留余数法。
(2)然而,对于不同的关键字可能得到同一哈希地址,即key1!=key2,而f(key1)=f(key2),这种现象叫做冲突,在一般情况下,冲突只能尽可能的少,而不能完全避免。因为,哈希函数是从关键字集合到地址集合的映像。通常,关键字集合比较大,它的元素包括多有可能的关键字,而地址集合的元素因为哈希表中的地址值。既然如此,那么,如何处理冲突则是构造哈希表不可缺少的一个方面了。。
通常用于处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等。。。
(3)在哈希表上进行查找的过程和哈希造表的过程基本一致。给定K值,根据造表时设定的哈希函数求得哈希地址,若表中此位置没有记录,则查找不成功;否则比较关键字,若何给定值相等,则查找成功;否则根据处理冲突的方法寻找“下一地址”,知道哈希表中某个位置为空或者表中所填记录的关键字等于给定值时为止。
2、问题描述
编写Hash表程序(女友软件技术基础的作业,要求哈希表、矩阵运算等,这里是哈希表的实现。。。)
关键字为整数,冲突解决用单向链表
Hash表建立函数 关键字搜素函数
3、解决方法:
(1)采用除留余数法构造哈希函数,冲突解决采用链地址法。
(2)具体的关键字列表为(19,14,23,01,68,20,84,27,55,11,10,79),则哈希函数为H(key)=key MOD 13。则采用除留余数法和链地址法后得到的预想结果应该为:
(3)哈希造表完成后,进行查找时,首先是根据哈希函数找到关键字的位置链,然后在该链中进行搜索,如果存在和关键字值相同的值,则查找成功,否则若到链表尾部仍未找到,则该关键字不存在。
4、具体的实现代码:
其中2.txt中内容为:12
19 14 23 1 68 20 84 27 55 11 10 79 第一个值12表示关键字的个数。其他为具体的关键字
#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(){ printf("关键字列表保存在2.txt文件中,其中第一个值为关键字的个数\n其他值为具体的关键字,各个关键字之间用空格隔开\n"); int i,k,m,n,num,flag,l,j; FILE *p; struct keyNum *head=NULL; //关键字列表保存在2.txt文件中,其中第一个值为关键字的个数 //其他值为具体的关键字,各个关键字之间用空格隔开 p=fopen("2.txt","r"); if(p==NULL) { printf("cannot open file 2.txt"); exit(0); } fscanf(p,"%d",&num); for(i=0;i<num;i++) hash[i]=NULL; for(i=0;i<num;i++) { fscanf(p,"%d",&k);//获取关键字 m=k%(num+1);//计算得到关键字的哈希值 hash[m]=insertHash(hash[m],k);//将关键字k插入到哈希值为m的链表中 } printf("-----------------------------------------------\n请选择要进行的操作:\n1、打印采用链地址法得到的哈希表\n"); printf("2、进行关键字查找\n3、退出\n------------------------------------------------\n"); scanf("%d",&flag); while((flag==1)||(flag==2)) { if(flag==1)//打印哈希表 { printf("采用链地址法得到的哈希表为:\n"); for(i=0;i<num+1;i++) { printf("第%d行:",i); print(hash[i]); printf("\n"); } } else //查找 { 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); else printf("整数值%d不在哈希表中!\n"); } printf("-----------------------------------------------\n请选择要进行的操作:\n1、打印采用链地址法得到的哈希表\n"); printf("2、进行关键字查找\n3、退出\n------------------------------------------------\n"); scanf("%d",&flag); }}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); } else printf("null");}
- 采用链地址法处理冲突构造哈希表
- 采用链地址法处理冲突构造哈希表
- 采用链地址法处理冲突构造哈希表
- 采用链地址法处理冲突构造哈希表
- 今天学了【链地址法处理冲突构造哈希表】,帮别人写了个程序。
- HASH表(采用开放地址法处理hash冲突)
- 链地址处理法构造简单哈希表
- 一段采用链地址法解决冲突的Hash代码
- 哈希表(链地址法处理冲突)(1012)
- 链地址处理哈希冲突的哈希表
- (6)散列冲突处理:链地址法
- (6)散列冲突处理:链地址法
- POJ 2002 Squares hash+链地址法处理冲突
- 哈希表构造与处理冲突方法
- SDUTOJ 1480 数据结构实验:哈希表——链地址法处理冲突
- 经典Hash实现(采用拉链法处理冲突)
- HASH表(采用链表处理hash冲突)
- 链地址处理哈希冲突方法
- mac系统下搭建android环境
- Java I/O读取键盘输入/编码格式
- scp
- eclipse使用国内镜像站点安装插件
- Testing the CATCHER
- 采用链地址法处理冲突构造哈希表
- Nginx和Tomcat安装记录
- JQuery基础核心
- hdu 4790 Just Random
- The things need to be done after installed Ubuntu
- Android 使用Intent 在Activity 间跳转
- POJ2251Dungeon Master&&nyoj523亡命逃窜
- 谷歌分析大数据怎么它就这么快?
- 如何使用st官网的库文件开发项目详细教程