Java数据结构与算法12——Hash表

1.Hash表是什么

Hash表(也称散列表)是一种能实现快速插入和查找操作的数据结构,采用根据关键码值(key)来获取对应Value的方式。把关键码值映射到Value的位置的函数称为Hash函数,而存放记录的数组就是Hash表。

Ant 127^2 + 1527 + 18
Apple 127^4 + 1627^3 + 1627^2 + 1327 +5
200034 % 10000 = 34 . 5位 zzzzz = 130

2.Hash表的优缺点

1.优点:Hash表的查找、插入和删除操作很快,比树快很多

2.缺点:Hash表是基于数组的,一旦创建就很难改变大小,有些Hash表被基本填满时,性能会明显下降

3.缺点:不方便顺序遍历表中数据因此Hash表适合于:不需要有序遍历数据,且可预测数据量大小的情况。

3.什么是Hash化

所谓Hash化指的就是:把数据中的关键字(关键字:可以用来识别或代表数据的内容,可以是数据本身,也可以是数据的一部分),转换成为对应的数组下标的过程,实现这个过程的函数就是Hash函数(或称散列函数)

4.Hash函数的过程以及构建

Hash函数的基本过程 :

  • step1.把关键字转换成为唯一的整数,通常这个整数范围非常大
  • step2.把这些整数压缩到可接受的数组的索引范围

常用的构造Hash函数的方法 :

  • 1.直接寻址法取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a*key + b,其中a和b为常数(这种散列函数叫做自身函数)
  • 2.数字分析法分析数据,找出其中数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址
  • 3.平方取中法取关键字平方后的中间几位作为散列地址
  • 4.折叠法将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。
  • 5.随机数法选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。
  • 6.除留余数法取关键字被某个不大于散列表表长的数除后所得的余数为散列地址。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。

5.Hash冲突及其解决,包括:开放地址法和链地址法

Hash冲突就是不同的关键字,经过Hash化后,得到相同的数组下标。

5.1 开放地址法

当冲突发生时,不再使用Hash函数,而是采用其它的方式,来找到一个未使用的数组地址。

1.线性探测就是从冲突处开始,依次向下查找未使用的地址,到底了就回到开头继续查找,这种方式容易产生聚集,聚集越大,性能会降低。哈希表中,一串连续的已填充单元叫做填充序列;如果加入新的数据项,使得填充序列也变长,这叫做聚集。

2.二次探测就是从冲突处开始,向下查找未使用的地址,每次增加步数的平方,从而加大探测的间隔,减少聚集的程度。它仍然会产生二次聚集的问题,毕竟步骤的平方也是固定的步长大小。

3.再哈希法就是从冲突处开始,向下查找未使用的地址,但是每次增加的步数,是使用不同的Hash函数,对关键字再次Hash的值,这样就不采用固定步长了。通常第二个Hash函数具有如下特点:
(1)和第一个Hash函数不同
(2)不能输出0,否则原地踏步,就死循环了建议采用公式:stepSize=常量 -(key % 常量),其中常量是小于数组容量的质数

5.2 链地址法

数组内不直接存放数据,而是存放实际存放数据的链表,这样当冲突发生时,数据直接加入到数组下标所指的链表中。

1.装填因子:指的是装入的数据个数和数组容量的比值。在开放地址法里面,装填因子会比1小,而链地址法里面,由于每个数组项指向一个链表,可以装载多个数据,因此这个装填因子可以比1大。在开放地址法里面,当装填因子到了一半或2/3后,性能下降很快;在链地址法里面就没有这个问题,因此链地址法更健壮。

2.重复:在链地址法里数据可重复,所有相同关键字值的项都放在同一个链表中

5.3 设计好的Hash函数

1.一定要能快速运算

2.关键字是随机的情况:采用index=key%arraySize是一个不错的选择

3.关键字不是随机的情况
(1)不要使用无用数据,比如校验和就可以不要
(2)使用所有的数据,关键字的每个部分,都应该在Hash函数中有所反映

4.使用质数作为取模的基数
使用质数能保证关键字较为平均的映射到数组中

6.Hash化字符串

Hash化字符串 Horner(英国数学家)数学恒等式,比如: var4n^4+ var3n^3+ var2n^2+ var1n^1+ var0可以转换成: (((var4n + var3)n + var2)n + var1)n + var0 。

7.Hash化的效率

如果没有发生冲突,插入、查找和删除都是O(1);如果发生冲突,就要依赖后面的探测长度了,而平均探测长度跟装填因子成正比。

8.了解Hash的应用

Hash除了用在快速访问数据的场景,还常用在信息安全领域的加密上。比如大家熟知的一些Hash算法:MD5、SHA-1、SHA-256等等。

参考

  • 1)Java数据结构和算法精讲版

你可能感兴趣的:(Java数据结构与算法12——Hash表)