开放定址法(线性探测),拉链法 -Hash算法

来源:互联网 发布:张恩民 php 编辑:程序博客网 时间:2024/05/01 12:39

总结:

哈希别名为:Hash 或者 散列表;
开放定址法是为了解决hash值碰撞后的处理;


哈希表查找(杂凑法):(http://c.biancheng.net/cpp/html/1031.html)
查找:(http://blog.csdn.net/yang_yulei/article/details/26104921)

散列表(哈希)是算法在时间和空间上作出权衡的经典例子。

如果没有内存限制,我们可以直接将键作为(可能是一个超大的)数组的索引,那么所有查找操作只需要访问内存一次即可完成。但这种情况不会经常出现,因此当键很多时需要的内存太大。
另一方面,如果没有时间限制,我们可以使用无序数组并进行顺序查找,这样就只需要很少的内存。而散列表则使用了适度的空间和时间并在这两个极端之间找到了一种平衡。

开放定址法

所谓开放定址法,即是由关键码得到的哈希地址一旦产生了冲突,也就是说,该地址已经存放了数据元素,就去寻找下一个空的哈希地址,只要哈希表足够大,空的哈希地址总能找到,并将数据元素存入。

线性探测法

Hi=(Hash(key)+di) mod m ( 1≤i < m )
其中:
Hash(key)为哈希函数
m 为哈希表长度
di 为增量序列1,2,……,m-1,且di=i
步骤:
而Hash(3)=3,哈希地址上冲突,由
H1=(Hash(3)+1) mod 11=4 仍然冲突;
H2=(Hash(3)+2) mod 11=5 仍然冲突;
H3=(Hash(3)+3) mod 11=6 找到空的哈希地址,存入。

原理:
这里写图片描述

当碰撞发生时,我们直接检查散列表中的下一个位置(将索引值加1),如果不同则继续查找,直到找到该键或遇到一个空元素。
注意:
Hash表的长要大于需要插入元素值,不然最后数据无法找到空元素。

二次探测法

Hi=(Hash(key)±di) mod m
其中:
Hash(key)为哈希函数
m 为哈希表长度,m 要求是某个4k+3 的质数(k 是整数)
di 为增量序列12,-12,22,-22,……,q2,-q2 且q≤1/2 (m-1)
步骤:
对关键码寻找空的哈希地址只有3 这个关键码与上例不同,
Hash(3)=3,哈希地址上冲突,由
H1=(Hash(3)+12) mod 11=4 仍然冲突;
H2=(Hash(3)-12) mod 11=2 找到空的哈希地址,存入。

双哈希函数探测法

Hi=(Hash(key)+i*ReHash(key)) mod m (i=1,2,……,m-1)
其中:
Hash(key),ReHash(key)是两个哈希函数,
m 为哈希表长度
步骤:
双哈希函数探测法,先用第一个函数Hash(key)对关键码计算哈希地址,一旦产生地址冲突,再用第二个函数ReHash(key)确定移动的步长因子,最后,通过步长因子序列由探测函数寻找空的哈希地址。

比如,Hash(key)=a 时产生地址冲突,就计算ReHash(key)=b,则探测的地址序列为
H1=(a+b) mod m,H2=(a+2b) mod m,……,Hm-1=(a+(m-1)b) mod m

拉链法

也就是这里说。(http://blog.csdn.net/cy_cai/article/details/53609019)

0 0