哈希查找

552 阅读3分钟

哈希查找是通过构建哈希表,并解决哈希冲突,在哈希表的基础上执行哈希查找的查找方式。

  • 算法流程:
  1. 通过特定的哈希算法构造哈希表
  2. 根据选择的冲突处理方法解决哈希冲突
  3. 在哈希表的基础上执行哈希查找
  • 复杂度分析:
  1. 如果没有空间限制,直接将键作为索引,时间复杂度为O(1)
  2. 如果没有时间限制,进行顺序查找,时间复杂度为O(n)
  • 哈希表 哈希表是,通过哈希计算得到的索引与要存储的之间一对一的对应关系。 可以把哈希表看做一个数组,每个索引都对应一个值,但是哈希表的索引不像数组那样0到length-1,而是通过哈希计算得到的。

  • 哈希函数 为了保证哈希表索引中索引和值得一对一关系,设计的固定算法。

特点:

  1. 每次计算都能得到固定长度的索引
  2. 相同的值,得到相同的索引
  3. 不同的值,大概率会得到不同的索引
  • 哈希冲突 当不相等的两个值,经过哈希计算得到同一个索引,这种情况就成为发生了哈希冲突。

  • 解决哈希冲突

  1. 开放定址法:我们在遇到哈希冲突时,去寻找一个新的空闲的哈希地址。

    举例:就是当我们去教室上课,发现该位置已经存在人了,所以我们应该寻找新的位子坐下,这就是开放定址法的思路。如何寻找新的位置就通过以下几种方法实现。

    1)线性探测法
     当我们的所需要存放值的位置被占了,我们就往后面一直加1并对m取模直到存在一个空余的地址供我们存放值,取模是为了保证找到的位置在0~m-1的有效空间之中。
    
     公式:h(x)=(Hash(x)+i)mod (Hashtable.length);(i会逐渐递增加1

    举例: 20210709200230651.png

存在问题:出现非同义词冲突(两个不想同的哈希值,抢占同一个后续的哈希地址)被称为堆积或聚集现象。

2)平方探测法(二次探测)
         当我们的所需要存放值的位置被占了,会前后寻找而不是单独方向的寻找。

         公式:h(x)=(Hash(x) +i)mod (Hashtable.length);(i依次为+(i^2)和-(i^2))

举例:

20210709202911464.png

  1. 再哈希法:同时构造多个不同的哈希函数,等发生哈希冲突时就使用第二个、第三个……等其他的哈希函数计算地址,直到不发生冲突为止。虽然不易发生聚集,但是增加了计算时间。

  2. 链地址法:将所有哈希地址相同的记录都链接在同一链表中。 公式:h(x)=xmod(Hashtable.length);

20210709221827318.png

  1. 建立公共溢出区:将哈希表分为基本表和溢出表,将发生冲突的都存放在溢出表中。

转自:

  1. blog.csdn.net/qq_48241564…
  2. www.jianshu.com/p/4e64fce04…
  3. www.cnblogs.com/maybe2030/p…