数据结构 哈希法的想法

二分法查找、二叉排序树、B树等这些查找算法,本质上是记录在列表中的相对位置是随机的。记录与关键字的大小没有直接关系。这就导致查找的效率依赖于查找过程中对关键字所进行的比较次数。

由此提出另一种新的算法——哈希法,负责解决因为与关键字比较次数过多而影响查询效率的问题。

哈希法

  • 哈希法(又称散列法、杂凑发、关键字地址计算法,由哈希法生成的表又称为哈希表、散列表、杂凑表等)。

  • 基本思想:首选在元素的关键字k和元素的存储位置p之间建立一个对应关系H,使得 p = H(k),H称为哈希函数。
    创建哈希表的时候,把关键字为k的元素直接存入地址为 H(k) 的单元;
    以后要查找关键字为k的元素时,再利用哈希函数计算出该元素的存储位置 p=H(k) , 从而达到按关键字直接存取元素的目的。
    由此可知,哈希法是计算式查找的方法。

想要使用哈希表进行查找,首先要明白哈希函数的构造方法

哈希函数的构造方法

原则:

便于计算;计算出来的地址相对均匀,目的是尽量减少冲突。(冲突是因为当关键字集合很大时,会出现 k1!=k2,但 H(k1) = H(k2))

1.数字分析法

方法:事先知道关键字集合,并且每个关键字的位数比哈希表的地址码位数多。从关键字中选出分布较均匀的若干位,构成哈希地址。

如:有80个记录,关键字为8位的十进制整数d1d2d3…d8,若哈希表长度为100,同时各关键字中d4和d7的取值分布范围较为均匀(减少冲突),则哈希函数为H(key)=H(d1d2d3…d8)=d4d7。例如H(82346522)=42,H(82316562)=16。

2.平方取中法

若无法确定关键字中哪几位分布均匀,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为哈希地址。(因为完成平方运算后中间几位的关键字中每一位都相关,故不同关键字会以较高的概率产生不同的哈希地址)

如:按字母顺序作为编号,A是01,K是11等。有几个字符串如:“KEYA”, “KYAB”, “AKEY”, “BKEY”。对于字符串 “KEYA”,其编码是11052501,对这个数进行平方运算得122157778355001。

假设对上面的字符串都进行了平方运算,发现得到结果的第7位到第9位分布比较均匀,不冲突,那么可以以它们为关键字创建哈希表。

3.分段叠加法

按哈希表地址位数将关键字分成位数相等的几部分(最后一部分可以较短),然后将这几部分相加,舍弃最高进位后的结果就是该关键字的哈希地址。具体方法有折叠法与移位法。移位法是将分割后的每部分低位对齐相加,折叠法是从一端向另一端沿分割界来回折叠(奇数段为正序,偶数段为倒序),然后将各段相加。

例如:有关键字key = 123 603 247 112 020 65,哈希表长度为1000,则应把关键字分成3位一段,在此舍去最低的两位65,分别进行移位叠加和折叠叠加,求得哈希地址为105和907。(选择其中一种方法求得哈希值即可)
在这里插入图片描述

4.除留余数法

假设哈希表长为m,p为小于等于m的最大素数,则哈希函数为 H(k) = k%p(%为取余)。

例如:已知散列函数为(18,46,75,54),其中表长 m=5, p=7,则有
H(18) = 18%7 = 4
H(46) = 46%7 = 4
H(75) = 75%7 = 5
H(54) = 54%7 = 5
冲突较大,那么可以取较大的m, p值,如m=p=13,那么结果:
H(18) = 18%13 = 5
H(46) = 46%13 = 7
H(75) = 75%13 = 10
H(54) = 54%13 = 2
没有冲突。

5.伪随机数法

采用一个伪随机数作为哈希函数,即H(key) = random(key)。

总之,一个好的哈希构造函数应考虑好五个因素:
①计算哈希函数所需时间(简单)。
② 关键字的长度。
③ 哈希表的大小。
④ 关键字分布的情况。
⑤ 记录查找的频率。

哈希函数冲突解决办法

1.开放定址法(再散列法)

基本思想:当关键字key的初始哈希地址 h0=H(key) 出现冲突时,以h0为基础,产生另一个地址h1,如果h1仍然冲突,再以h0为基础,产生另一个哈希地址h2…直到找出一个不冲突的地址hi,将相应元素存入其中。

hi = (h0+di)%m,i =1,2,3…n
其中 H(key)为哈希函数,h0=H(key),m为表长,di为增量序列。
增量序列的取值方式不同,相应的再散列方式也不同。
① 线性探测再散列

di = 1,2,3,…,m-1

② 二次探测再散列

di =

③ 伪随机探测再散列
di = 伪随机数列
具体实现时,应建立一个伪随机数发生器。

2.再哈希法

同时构造多个不同的哈希函数:
Hi = RHi(key) i =1,2,3,…,k
当哈希地址H1 = RH1(key) 发生冲突时,再计算H2 = RH2(key)…直到冲突不再冲突产生。这种方法不易产生聚集,但增加了计算量。

3.链地址法

将所有哈希地址为i的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。链地址法适用于经常进行插入和删除的情况。

4.建立公共溢出区

将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素一律填入溢出表。
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值