Hash算法

一、Hash表

Hash表也叫散列表,它是基于告诉存取的角度设计的,也是一种典型的“空间换时间”的做法。该数据结构是一个线性表,但是其中的元素不是紧密排列的,而是可能存在空隙。访问数据是根据key-value来访问,它通过关键码key映射到表中的一个位置来访问记录,以加快查找的速度。

几个关键词:

  • hash函数:也叫散列函数,用于通过key计算位置的函数。

  • 负载因子:散列表的空间占有率,比如100个元素的空间存储了70个元素,70/100=0.7就是负载因子。

  • 桶:每个存储单位成为桶。设一个散列表有M个桶,那么散列函数的值域应该是[0,M-1]。

  • 散列冲突:当两个不同的key通过散列函数计算的结果相同时,我们称这个叫做冲突。

二、Hash冲突

产生冲突主要取决于:

  • 散列函数,一个好的散列函数的值应该尽可能平均分布。

  • 处理冲突的方法。

  • 负载因子的大小,太大不一定就好,并且浪费空间严重,负载因子和散列函数式联动的。

解决冲突的办法:

  • 开放定址法:从发生冲突的那一个单元起,按照一定的次序从哈希表找到一个空闲的单元存入,常用的开放定址法有:线性探查法,平方探查法,双散列函数探查法。

  • 拉链法:将hash相同的值构成一个单链表,jdk7的hashmap就是这么解决hash冲突的。

  • 再哈希法:同时构造多个不同的哈希函数,当第一个哈希函数产生冲突时,用第二个哈市函数计算,知道不再产生冲突,这样不易产生聚集,但是增加了计算时间。

  • 建立公共溢出区:将哈希表分为公共表和溢出表,当溢出发生时,将所有溢出数据统一放到溢出区。

三、常用Hash算法

Hash函数能够简单的划分为如下几类:

  • 加法Hash

  • 位运算Hash

  • 乘法Hash

  • 除法Hash

  • 查表Hash

  • 混合Hash

3.1 加法Hash

3.2 位运算Hash

3.3 乘法Hash

3.4 除法Hash

除法运算hash与乘法类似,但是除法运算太耗时,一般不使用

3.5查表Hash

3.6 混合Hash

混合hash,就是利用了以上对种方式,各种常见的hash算法比如md5等属于这个范畴

参考:

解决哈希冲突的常用方法分析:https://www.jianshu.com/p/4d3cb99d7580

常见Hash算法的原理:http://blog.jobbole.com/106733/

Last updated

Was this helpful?