哈希表小结

  • 什么是哈希表?

理想情况是希望不经过任何比较,一次存取便能得到所查记录,那就必须在记录的存储位置 f(k) 和它的关键字 k 之间建立一个确定的关系 f 。使每个关键字,通过f(k)找到对应的存储位置。因此不需要任何比较便能得到所查记录。为此,我们称这个对应关系 f 为哈希函数(Hash),按这个思想建立的表为哈希表

哈希函数就像在新华字典查找一个字,按拼音或笔画(key) 先查到页数( f(key) 地址) ,再去对应页数找对应的字(记录)。

如果不是按这样来,那就需要从字典的第一个字开始比较,直到比较得到一个字与你要的字相等,这样也太麻烦了。

  • 哈希碰撞/冲突

我们的理想是对于同一个key只有一个哈希地址与之对应。但现实不是这样的,可能不同的key,却可以得到相同的哈希地址,因为 f(key) 它只能保证你输入一个key,它能给你一个哈希地址。但是并不能保证 f(k1) != f(k2)。就像查字典,你并不能保证按不同的拼音查可以得到不同的页数,因为也可以得到相同的页数,就比如多音字。这一现象称为冲突/哈希碰撞。冲突只能尽可能地少,不能完全避免。

  • 哈希表

用哈希函数 H(key) 将一组关键字映像到一个有限的连续的地址集上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这种表便称为哈希表。这个过程称为哈希造表散列,所得的储存位置称哈希地址散列地址。所以哈希表也称散列表

  • 哈希函数的构造方法

直接定址法   H(key) = key 或 H(key) = a*key + b

数字分析法

平方取中法

折叠法

除留余数法   H(key) = key MOD p ,p <= m (m为哈希表长)

随机数法

一个好的哈希表取决于好的哈希函数,好的哈希函数取决于好的构造方法。这里不详细介绍构造方法了。

  • 处理哈希碰撞的方法

1.开放定址法   

H(i) = ( H(key) + d_{i} ) MOD m    ,【 i=1,2,...,k  (k<= m-1) 】

H(key) 为哈希函数(发生碰撞时则使用H(i))   m为哈希表表长    d_{i}为增量序列   MOD是取余

所以根据 增量序列 的不同表示,又分三种:

d_{i}  = 1,2,3,...,m-1 时,称线性探测再散列

d_{i} = 1^{2},2^{2},3^{2},...,,-1^{2},2^{2},3^{2},...,2^{2},-2^{2},...,\pm k^{2} 时,称二次探测再散列

d_{i}  = 伪随机序列 时,称随机探测再散列

至于上面说的是啥意思,看一个例子:

2.再哈希法

H(i) = RH(key)   ,i=1,2,...,k

R 和 H 均是不同的哈希函数,当H(key)产生的地址冲突时,用H(i)计算得到新的哈希地址,直到不发生冲突。

3.链地址法

将所有关键字为同义词的记录存储在同一线性链表中。看一个例子:

4.建立一个公共溢出区 不详细介绍了

猜你喜欢

转载自blog.csdn.net/qq_38261174/article/details/81327979