什么是Hash

参考自链接: javascript:void(0).

哈希(hash)表的定义
哈希表是一种根据关键码去寻找值的数据映射结构,该结构通过把关键码映射的位置去寻找存放值的地方。就是通过key值然后按照某种哈希函数 hash() 计算hash(key),得到的就是哈希值。

什么是hash冲突呢?
我们知道不同的数字通过一个函数结果可能会一样,那么不同的值通过hash()计算得到的hash值也可能是一样的,假如数组中的3号位有对象占着,此时 ,又来了另一个对象,通过hash算法,发现坐标也是数组中的3号位,此时就发生了hash冲突。
注意:哈希冲突是无可避免的

那么解决办法是什么呢
最常用的就是开发定址法链地址法。

开发定址法

就是当发生hash冲突时,找hash表剩下空余的空间,找到空余的空间然后插入。但是也有一个问题就是如果空间不足,那他无法处理冲突也无法插入数据,因此需要装填因子(插入数据/空间)<=1。
怎么理解 Hash_数据结构

链地址法

链地址法的原理时如果遇到冲突,他就会在原地址新建一个空间,然后以链表结点的形式插入到该空间。我感觉业界上用的最多的就是链地址法。看下图,比如我现在有一堆数据{1,12,26,337,353…},而我的哈希算法是H(key)=key mod 16,第一个数据1的哈希值f(1)=1,插入到1结点的后面,第二个数据12的哈希值f(12)=12,插入到12结点,第三个数据26的哈希值f(26)=10,插入到10结点后面,第4个数据337,计算得到哈希值是1,遇到冲突,但是依然只需要找到该1结点的最后链结点插入即可,同理353。
怎么理解 Hash_java_02

关于哈希表的性能

由于哈希表高效的特性,查找或者插入的情况在大多数情况下可以达到O(1),时间主要花在计算hash上,当然也有最坏的情况就是hash值全都映射到同一个地址上,这样哈希表就会退化成链表,查找的时间复杂度变成O(n),但是这种情况比较少,只要你不把hash计算的公式外漏出去并且有人故意攻击(用兴趣的人可以搜一下基于哈希冲突的拒绝服务攻击),一般也不会出现这种情况。
怎么理解 Hash_结点_03