面试对线记录17 Hash冲突的解决办法

今天在和一位面试官对线时,这位面试官问的好多都是基础题,讲真,,,,学了这么久,好多都不会了,但是面试就是在不断的对线中越来越nb的嘛,所以开个小版块来记录一下。 hash算法按照我的理解,可以视为一个黑盒,把一个任意长的输入,通过Hash算法来变换成固定长度的输出,这个没什么好说的,Java中的HashMap底层原理粗略就是这样子。由此就可以引出一个叫做哈希表也可以叫做散列表的概念,就是说每一个输入都在哈希表中可以找到一个位置,一个萝卜一个坑的意思。但是什么算法都会有一些问题,比如有些输入在经过hash算法的处理,发现算出来的那个坑坑有萝卜了,这种现象就叫做hash冲突。也就引出来解决这个问题的三大方法:开放定址法,链地址法,再哈希法。

  1. 开放定址法 按照我的理解,就是说当发生哈希冲突时,萝卜B被分到一个萝卜A的坑坑了,这个时候就以萝卜A的地址为基准,根据再寻址的方法在找一个萝卜B的位置,如果找到这个地址了,还是冲突了,那就再寻址,一直到找到为止,寻址方法有线性探查(萝卜B就往A的后面位置一个一个数,一直到找到一个空位为止),二次探查(在萝卜B的周围反复横跳,+1,-1,+2,-2, … ,+n,-n),一直到找到一个不冲突的位置为止,伪随机探测(使用一个伪随机数生成器,然后以萝卜B为基准,加上这个产生的随机数产生的位置)当然这个算法的前提就是整个地址空间不是FULL状态。
  2. 链地址法 这个就是HashMap的底层实现方法了,就是说在发生哈希冲突的时候,我们在这个坑坑上栽上个竹竿,然后把萝卜按照先后顺序挂在竹竿上。用代码来说就是在发生哈希冲突的哈希地址上建立一个链表(红黑树),哈希地址算出来相同的输入挂在链表(红黑树)上。
  3. 再哈希法 这个接着哈希就行了。。。。一直哈到有坑坑为止,有点像递归,这种方法很耗费时间