标签:
1.哈希(Hash)函数
如果能在关键字与记录保存的位置之间建立一种联系,则可以不经过比较,直接对关键字进行计算得出记录保存的位置,再到相应位置去读取数据即可。将这种关键字与记录保存位置之间的对应关系称为哈希(Hash)函数,将按这种方式建立的表称为哈希表。
2.哈希表的基本思想是:以线性表中每个元素的关键字key为自变量,通过一定的函数关系h(key)计算出函数的值,把这个值作为数组的下标,将元素存入对应的数组元素中。
函数h(key)称为哈希函数,函数的值称为哈希地址。
在查找时,根据关键字key,用同样的哈希函数h(key)计算得出哈希地址,然后到相应的数组中取出要找的元素。
3.构造哈希函数
(1)直接定址法
直接定址法是以关键字key本身或关键字key加上某个常数C,用来作为哈希地址,即
h(key) = key + C
当C为0时,哈希地址就是关键字本身。
(2)除法取余法
除法取余法就是用关键字key除以散列表长度n,得到的余数作为哈希地址。
(3)数字分析法
数字分析法是取关键字key中某些比较分散的数字作为散列地址的方法。
(4)平方取中法
平方取中法是将关键字key求平方后,取中间的几位数字作为哈希地址的方法。
(5)折叠法
折叠法是先将关键字key按哈希地址要求的位数分成长度相等的几段,最后一段的长度可能会短些。接着将这几段进行求和,然后去掉最高位的进位,将得到的值作为散列地址。
4.处理冲突
(1)开放地址法
所谓开放地址,就是哈希表中尚未使用的数组元素的地址。
开放地址法就是从发生冲突的那个数组元素开始,按一定的次序,从哈希表中查出一个空闲的数组元素,把发生冲突的待插入元素存入到该数组元素中。
使用开放地址法解决冲突,其主要就是需要寻找开放地址。需找开放地址的方法通常有线性探测法和双散列探测法两种。
1)线性探测法从发生冲突的单元起,在哈希表中按顺序向后探测,直到找到开放地址为止,若到哈希表末尾仍未找到开放地址,则放回哈希表的首端再向后探测。这样,只要表中有开放地址,总会被找到。
2)双散列函数探测法
双散列函数探测法使用两个散列函数h和h1,其中h为主散列函数,h1为次散列函数。当由h(key)计算的地址被占用时,向后移动h1(hey)个单元再探测开放地址,若探测的地址仍不是开放的,可逐次向后移h1(key)个单元进行探测,若到散列表的末尾仍未找到开放地址,则从散列表的首端再向后探测,直到找到开放地址为止。
(2)链接法
链接法是在哈希表的每个存储单元中增设一个指针域,将哈希地址相同的元素链接起来。
这种方法将占用更多的内存空间,但其优点是查找速度快,不需进行多次探测。
5.哈希表的查找
1 //----------------开放定址哈希表的存储结构----------------------- 2 int hashsize[] = {997,...}; //哈希表容量递增表,一个合适的素数序列 3 typedef struct{ 4 ElemType *elem; //数据元素存储基址,动态分配数组 5 int count; //当前数据元素个数 6 int sizeindex; //hashsize[sizeindex]为当前容量 7 }HashTable; 8 9 #define SUCCESS 1 10 #define UNSUCCESS 0 11 #define DUPLICATE -1 12 13 Status SearchHash(HashTable H,KeyType K,int &p,int &c){ 14 //在开放地址哈希表H中查找关键码为K的元素,若查找成功,以p指示待查数据元素在表中位置,并返回SUCCESS;否则,以p指示插入位置,并返回UNSUCCESS,c用以计冲突次数,其初值置零,供建表插入时参考 15 p = Hash(K); //求得哈希地址 16 while(H.elem[p].key != NULLKEY && !EQ(K,H.elem[p].key)) //该位置中填有记录并且关键字不相等 17 collision(p,++c); //求得下一探查地址p 18 if EQ(K,H.elem[p].key) 19 return SUCCESS; //查找成功,p返回待查数据元素位置 20 else 21 return UNSUCCESS; //查找不成功(H.elem[p].key == NULLKEY),p返回的是插入位置 22 }//SearchHash
1 //----------通过调用查找算法实现了开放定址哈希表的插入操作------------ 2 Status InsertHash(HashTable &H,Elemtype e){ 3 //查找不成功时插入数据元素e到开放定址哈希表H中,并返回OK;若冲突次数过大,则重建哈希表 4 c = 0; 5 if(SearchHash(H,e.key,p,c)) 6 return DUPLICATE; //表中已有与e有相同关键字的元素 7 else if(c<hashsize[H.sizeindex]/2){ //冲突次数c未达到上限,(c的阀值可调) 8 H.elem[p] = e; ++H.count; return OK; //插入e 9 } 10 else 11 {RecreateHashTable(H);return UNSUCCESS;} //重建哈希表 12 }//InsertHash
标签:
原文地址:http://www.cnblogs.com/wxb713/p/4343873.html