数据结构知识整理 - 哈希查找(散列查找)

版权声明: https://blog.csdn.net/Ha1f_Awake/article/details/85620596

主要内容

数字分析法

平方取中法

折叠法

除留余数法

开放地址法

链地址法


 

前提

如果在数据元素的存储位置和其关键字之间建立某种直接关系,那么在进行查找时,就无需逐个比较关键字或者只做少数次的比较,并按照直接关系由关键字找到相应的记录,这就是散列查找法(Hash Search)的思想。它通过对元素的关键字值进行某种运算,直接求出元素的地址。

基本概念:

1)散列函数:p = H(key);p表示散列地址,key表示关键字,函数H()表示关键字与存储位置之间的某种关系。

2)散列表:一维数组,数组下标表示散列地址。

3)冲突、同义词:不同的关键字可能会求得同一个散列地址,这样的情况称为冲突,造成这种情况的关键字称为同义词

在实际应用中,理想化的、不产生冲突的散列函数是基本不存在的,这是因为散列表的关键字取值集合往往大于空间的地址集合。

散列函数是多对一的映射,冲突是不可避免的。我们只能根据具体情况,构造一个尽可能减少冲突的散列函数。

而一旦冲突发生,我们必须采取相应的措施及时予以处理。

综上所述,散列查找主要研究两个问题:

1. 构造散列函数;

2. 处理冲突。


 

构造散列函数

构造散列函数的方法很多,具体问题具体构造。

数字分析法

事先知道所有关键字值的规律,若关键字值的某些部分取值相同或只能取个别值,则取各关键字中若干位取值比较随机的数字作为散列地址,或通过一定的计算求出散列地址。

例如,同一届学生的出生日期,年份基本相同,若根据年份来计算散列地址,那显然是不可取的;只取月份或日份也会出现冲突,但冲突概率会减小,如果进一步根据月份和日份来计算散列地址,地址将会更加随机,冲突概率进一步减少。

平方取中法

通常情况下,我们很难得知所有关键字值的规律,取其中的某几位也不一定合适,而一个关键字值平方后的中间几位数和关键字值的每一位都相关。如果取关键字值平方后的中间几位或者组合来作为散列地址,得到的地址将会更加随机,具体所取位数与表长相关。

折叠法

将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(舍去进位)作为散列地址。数位叠加可以有移位叠加和间界叠加两种方法。移位叠加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加。

例如,关键字key=45387765213

1)移位叠加:453+877+652+13=995

2)边界叠加:

453+

778+

652+

31=914

除留余数法

取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key%p,p<=m。

不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模,这样能够保证散列地址一定落在散列表的地址空间中。

对p的选择很重要,一般取素数m,若p选的不好,容易产生同义词。


处理冲突

处理冲突的方法与散列表本身的组织形式有关。

开放地址法

基本思想:当一个记录的散列地址发生冲突时,以初始散列地址H0为基础,采取合适的方法计算另一个地址Hi,若另一个地址仍是冲突,继续计算,直至找到空地址为止。寻找新地址的过程称为“探测”。

Hi = (H(key) + di) % m

1. 线性探测法

将散列表看作循环表,从初始散列地址H0开始逐个寻找。若找不到,则说明散列表已满,需要进行溢出处理。

di = 1,2,...m-1

优点:只要散列表未满,必定可以找到新的散列地址。

缺点:可能产生“二次聚集”现象,即初始散列地址不同的元素可能会争夺同一个新地址。

2. 二次探测法

di = 1²,-1²,2²,-2²,3²,-3²,...

3. 伪随机探测法

di = 伪随机数序列(任意的数)

优点:避免了“二次聚集”现象。

缺点:不能保证一定可以找到一个新的散列地址。

链地址法

把具有相同散列地址的记录放在同一个单链表中,称为同义词链表。

m个散列地址就有m个单链表,同时将各链表的头指针放入一个一维数组中统一管理。

这种构造方法在具体实现时,依次计算各个关键字的散列地址,然后根据散列地址将数据元素插入到相应的链表中。

单链表上的查找过程仍然是给定值和关键字值比较的过程。


散列查找

散列查找的过程与构造散列表的过程基本一致。

虽然散列表在关键字与记录的存储位置之间建立了直接映像,但由于“冲突”的产生,散列表的查找过程仍然是一个给定值与关键字值比较的过程。

需要比较的关键字个数取决于三个因素:散列函数处理冲突的方法装填因子(散列表记录个数 / 散列表长度)。

猜你喜欢

转载自blog.csdn.net/Ha1f_Awake/article/details/85620596