这里解决冲突的方法是开放地址法:“开放地址指的是表中尚未被占用的地址,开放地址法就是当冲突发生时候,形成一个地址序列,沿着这个序列逐个进行探测,直到找到一个空的开放地址,将发生冲突的关键字存放到该地址中去,即Hi=(H(key)+di)%m,i=1,2,..k(k<=m),其中H(key)为散列函数,m为散列表长,di为增量序列。
例题:选取散列函数H(K)=(3K)%11,用开放地址处理冲突,d1=H(K);di=(di+(7K)%10+1)%11(i=2,3,..),试着在HT[0,..10]的散列地址空间对关键字{22,41,53,46,30,13,1,67}构造散列表,并求出在等概率下查找成功的平均长度,并设计构造散列表的完整算法程序。
测试数据:{22,41,53,46,30,13,1,67}
输出:i=0 22 i=1 13 i=2 41 i=3 1 i=4 30 i=5 53 i=6 46 i=10 67
cs=18 ASL=2.25
1算法思想:构造散列表是根据散列表函数核处理冲突的方法,将不同关键字的记录存储到不同的散列表地址的过程,所以主要操作是运用散列函数求出散列地址,如果冲突解决冲突,确保不同关键字的记录存储到不同的散列地址。
2.数据结构和散列函数及冲突解决方法选:取散列函数H(K)=(3K)%11,用开放地址处理冲突,d1=H(K);di=(di+(7K)%10+1)%11(i=2,3,..)
3.模块划分 (1)散列空间数组的初始化InitHash;(2)散列函数Hash (3)插入函数InsertHash (4)查找函数SearchHash (5)主函数
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define n 8 4 #define m 11 5 void InitHash(int HT[]) 6 { 7 /*对存储记录的散列表数组用整数0初始化*/ 8 int i; 9 for(i=0;i<m;i++) 10 HT[i]=0; 11 } 12 int Hash(int key) 13 { 14 /*散列函数*/ 15 return (3*key)%m; 16 } 17 void InsertHash(int HT[],int key) 18 { 19 /*插入函数,将key插入散列表HT中*/ 20 int d,s1,d1,h,temp; 21 h=Hash(key);/*调用散列函数计算散列地址*/ 22 s1=d1=h;/*保留散列地址,以备解决冲突时使用*/ 23 if(HT[h])/*判断是否冲突,如果冲突,用开放地址法第一次解决冲突*/ 24 h=(d1+s1)%m; 25 d=d1; 26 while(HT[h]) 27 { 28 /*解决第二次及以后冲突*/ 29 temp=d; 30 d=(temp+(7*key)%10+1)%m;/*计算di(i=2,3..)*/ 31 h=(s1+d)%m; 32 } 33 HT[h]=key; 34 35 } 36 int searchHash(int HT[],int key) 37 { 38 /*在散列表中查找key,如果找到,返回比较次数,否则返回-1*/ 39 int d,s1,d1,h,temp,sum; 40 h=Hash(key); 41 s1=h;d1=s1;d=d1; 42 if(HT[h]==key) return 1; 43 else{ 44 h=(d1+s1)%m; 45 if(HT[h]==key)return 2; 46 sum=1; 47 while(HT[h]) 48 { 49 if(HT[h]==key)return ++sum; 50 else{ 51 sum++;temp=d; 52 d=(temp+(7*key)%10+1)%m; 53 h=(s1+d)%m; 54 } 55 } 56 } 57 return -1; 58 } 59 int main() 60 { 61 // printf("Hello world!\n"); 62 /*输出每个记录在散列表中的位置,并计算出总的查找次数和平均查找长度*/ 63 int x[n]={22,41,53,46,30,13,1,67}; 64 int ht[m],sum,i; 65 double cs; 66 InitHash(ht); 67 for(i=0;i<n;i++) 68 InsertHash(ht,x[i]); 69 for(i=0;i<m;i++) 70 if(ht[i]!=0) 71 printf("i=%d %d ",i,ht[i]); 72 73 printf("\n"); 74 cs=0; 75 for(i=0;i<n;i++){ 76 sum=searchHash(ht,x[i]); 77 if(sum!=-1) 78 cs+=sum; 79 } 80 printf("cs=%f\n",cs); 81 printf("ASL=%f\n",(cs)/n); 82 return 0; 83 }
读书笔记= =