数据结构实验之查找七:线性之哈希表
Time Limit: 1000MS
Memory Limit: 65536KB
Problem Description
根据给定的一系列整数关键字和素数p,用除留余数法定义hash函数H(Key)=Key%p,将关键字映射到长度为p的哈希表中,用线性探测法解决冲突。重复关键字放在hash表中的同一位置。
Input
连续输入多组数据,每组输入数据第一行为两个正整数N(N <= 1500)和p(p >= N的最小素数),N是关键字总数,p是hash表长度,第2行给出N个正整数关键字,数字间以空格间隔。
Output
输出每个关键字在hash表中的位置,以空格间隔。注意最后一个数字后面不要有空格。
Example Input
5 5 21 21 21 21 21 4 5 24 15 61 88 4 5 24 39 61 15 5 5 24 39 61 15 39
Example Output
1 1 1 1 1 4 0 1 3 4 0 1 2 4 0 1 2 0
#include<stdio.h> #include<malloc.h> #include<math.h> #define N 10005 int Check[N]; int ImportData[N]; int P(int n){ for(int i=2;i<=sqrt(n);i++){ if(n%i==0) return 0; } return 1; } int HashFunction(int key,int n){ return key%n; } void Output(int a[],int n){ for(int i=0;i<n;i++){ printf("%d ",a[i]); } printf("\n"); } void Inputdata(int a[],int data[],int maxprime,int len,int num){ for(int i=0;i<num;i++){ int index=HashFunction(data[i],maxprime); if (a[index]==data[i]){ continue; } if(!Check[index]){ a[index]=data[i]; Check[index]=1; } else{ for(int j=index+1;j!=index;j++){ if(j>=len){ j=0; } if (a[j]==data[i]){ break; } if(!Check[j]){ a[j]=data[i]; Check[j]=1; break; } } } } } void InitTable(int a[],int n){ for(int i=0;i<n;i++){ Check[i]=0; a[i]=0; } } int Hash_Search(int key,int data[],int maxprime){ int index=HashFunction(key,maxprime); if(!data[index]) return 0; if(data[index]==key){ return index; } else{ for(int i=1;i<maxprime;i++){ index=HashFunction(key+i,maxprime); if(!data[index]){ return 0; } if(data[index]==key){ return index; } } return 0; } } int main(){ int n,num; while(scanf("%d %d",&num,&n)!=EOF){ int * data=(int *)malloc(sizeof(int)*n); InitTable(data,n); int maxprime; int i=num; while(1){ if(P(i)){ maxprime=i; break; }//最小素数 i++; } for(int j=0;j<num;j++){ scanf("%d",ImportData+j); } Inputdata(data,ImportData,maxprime,n,num); for(int k=0;k<num;k++){ k!=num-1?printf("%d ",Hash_Search(ImportData[k],data,maxprime)):printf("%d\n",Hash_Search(ImportData[k],data,maxprime)); } data=NULL; } return 0; }
除留余数法:hash函数 H(key)=key%p p为小于表长的最大质数,此题中为大于表长的最小质数。
解决冲突的方式:线性探测法、开放地址法(以空间为代价)、二次探测法
散列表的填装因子A
A=表中存在记录数/表的总长度,表示散列表的装满程度,A值越小发生冲突的可能性越小,反之冲突的可能性越大。在创建Hash表的过程中随着元素的装入,发生冲突的概率逐渐增大。