散列查找(HashSearch)


散列查找法(HashSearch)

  • 散列查找法(HashSearch)的思想,它通过对元素的关键字值进行某种运算,直接求出元素的地址,即使用关键字到地址的直接转换方法,而不需要反复比较。因此,散列查找法又叫杂凑法或散列法。
  • 散列(Hashing)通过散列函数将要检索的项与索引(散列,散列值)关联起来,生成一种便于搜索的数据结构(散列表)。
  • 散列的概念属于查找,采用直接寻址技术。在理想情况下,查找的期望时间为O(1)。
  • 散列函数和散列地址:在记录的存储位置p和其关键字key之间建立一个确定的对应关系H, 使 p=H(key), 称这个对应关系H为散列函数,p为散列地址。
  • 散列表:一个有限连续的地址空间,用以存储按散列函数计算得到相应散列地址的数据记录。通常散列表的存储空间是一个一维数组,散列地址是数组的下标。
  • 冲突和同义词:对不同的关键字可能得到同一散列地址,即key!=key2 ,而H(key1)=H(key2),这种现象称为冲突。具有相同函数值的关键字对该散列函数来说称作同义词,key1, 与key2互称为同义词。

hash函数

hash函数就是把任意长的输入字符串变化成固定长的输出字符串的一种函数。

输出字符串的长度称为hash函数的位数。

哈希函数构造考虑

  1. 散列表的长度;关键字的长度;关键字的分布情况;
  2. 散列函数的计算简单,快速;
  3. 散列函数能将关键字集合K均匀地分布在地址集{0,1,…,m-1}上,使冲突最小。

哈希函数的构造方法

1. 直接定址法

取关键字或关键字的某个线性函数值为哈希地址:H(key) = key 或 H(key) = a*key + b
其中a和b为常数,这种哈希函数叫做自身函数。

注意:由于直接定址所得地址集合和关键字集合的大小相同。因此,对于不同的关键字不会发生冲突。但实际中能使用这种哈希函数的情况很少

2. 相乘取整法

首先用关键字key乘上某个常数A(0 < A < 1),并抽取出key*A的小数部分;然后用m乘以该小数后取整。

注意:该方法最大的优点是m的选取比除余法要求更低。比如,完全可选择它是2的整数次幂。虽然该方法对任何A的值都适用,但对某些值效果会更好。Knuth建议选取 0.61803……。

3. 平方取中法

取关键字平方后的中间几位为哈希地址。通过平方扩大差别,另外中间几位与乘数的每一位相关,由此产生的散列地址较为均匀。这是一种较常用的构造哈希函数的方法。

4. 除留余数法

取关键字被数p除后所得余数为哈希地址:H(key) = key mod p (p ≤ m)。

注意:这是一种最简单,也最常用的构造哈希函数的方法。它不仅可以对关键字直接取模(MOD),也可在折迭、平方取中等运算之后取模。值得注意的是,在使用除留余数法时,对p的选择很重要。一般情况下可以选p为小于表长的最大质数。

5. 随机数法

选择一个随机函数,取关键字的随机函数值为它的哈希地址,即 H(key) = random (key);

通常,当关键字长度不等时采用此法构造哈希函数较恰当。

实际应用的哈希函数

目前应用最为广泛的hash函数是SHA-1和MD5算法,大多是128位和更长。

哈希冲突

哈希一定会存在冲突,所以需要解决冲突的办法。

1. 开放地址法

地址H0=H(key)发生冲突时,以H0为基础 ,采取合适方法计算得到另一个地址H1, 如果H1仍然发生冲突,以H1为基础再求下一个地址H2,若H2仍然冲突,再求得H3。依次类推,直至Hk不发生冲突为止,则Hk为该记录在表中的散列地址。

这种方法在寻找"下一个"空的散列地址时,原来的数组空间对所有的元素都是开放的,所以称为开放地址法。通常把寻找"下一个"空位的过程称为探测。上述方法可用如下公式表示:
Hi = (H(key) +di) % m ; i= 1, 2, …,k(k<=m-1)
其中H(key)称为散列函数,m为表长,di为增量序列;
增量 d 可以有不同的取法,并根据其取法有不同的称呼:
( 1 ) d i = 1 , 2 , 3 , …… 线性探测;
( 2 ) d i = 1^2 ,- 1^2 , 2^2 ,- 2^2 , k^2, -k^2…… 二次探测;
( 3 ) d i = 伪随机数 伪随机探测;
当表中 i, i+ 1, i+2 位置上已填有记录时,下一个散列地址为i、i+1 、i+2 和i+3 的记录都将填入i+3 的位置,这种在处理冲突过程中发生的两个第一个散列地址不同的记录争夺同一个后继散列地址的现象称作"二次聚集"或称作"堆积",即在处理同义词的冲突过程中又添加了非同义词的冲突。

  • 线性探测法的优点是:只要散列表未填满,总能找到一个不发生冲突的地址。缺点是:会产生"二次聚集"现象。
  • 二次探测法和伪随机探测法的优点是:可以避免"二次聚集"现象。缺点也很显然:不能保证一定找到不发生冲突的地址。

2. 链地址法

链地址法的基本思想是:把具有相同散列地址的记录放在同一个单链表中,称为同义词链表。有 m 个散列地址就有 m 个单链表,同时用数组HT[0…m-1]存放各个链表的头指针,凡是散列地址为i的记录都以结点方式插入到以 HT[i]为头结点的单链表中。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM