Skip to content

Latest commit

 

History

History
46 lines (25 loc) · 3.01 KB

哈希表-哈希冲突原理.md

File metadata and controls

46 lines (25 loc) · 3.01 KB

哈希表-哈希冲突原理

image-20221228145623734

电话号码簿举例

通过“王小一”的名字,首先get到W大写首字母的位置(这一步就是哈希函数映射的作用!),然后翻看字典根据W栏,找到其里面的“王小一”。当同时存在“王小二”的时候,同样首先根据哈希函数,找到W大写首字母的位置,然后发现W栏的下面,已经填上了“王小一”(这就是哈希冲突!),此时怎么办?就继续在王小二的后面,以链表连接的形式,继续连接上“王小二”。

  1. 王小一----hash映射----W的位置
  2. W的位置----王小一----王小二(遇到hash冲突,链式法则让王小二继续链接在王小一的后面)

上述的例子,可以很好地理解hash函数的作用,可以很好地理解hash冲突,但没看到键-值对(key-value,即entry),理论上应该是unordered_set的原理,接着看下面的unordered_map原理的例子。

学号key-姓名val举例

image-20221107170313395

  1. 首先,拿key:101011用hash函数找到数组里,该entry的位置,即idx:1,即key:101011----hash函数----idx:1。
  2. 然后,在idx:1这找其指向的是什么entry,显然指的entry是key:101011 val:张三。
  3. 此时,如果拿李四的学号来找,即key:102011----hash函数----idx:1,用hash函数映射也是1,那么就发生hash冲突,此时将李四link在张三后面。

总结

  • hash函数设计越好,冲突就越少发生。

  • hash的结构

    数组+链表,或数组+二叉树(拉链法)

    数组(开放寻址法、 open address)。

  • hash冲突的解决方式

    对于开放寻址法,最典型为线性探测(linear probing),即当前位置如果冲突,直接顺延到下一位置。

    对于拉链法,则往后面链接node即可。

  • 解决hash冲突,除了拉链法,还有开放寻址法,即如果idx:1上冲突了,就继续放在后面即2上,如果2也已经填了,就继续往后排放,空间不够就扩容,Java的ThreadLocal就是开放寻址法。

  • Java的HashMap是拉链法,对于HashMap,当某个idx位置的链表长度大于8,链表会转换成树,小于6时,又会转换回为链表,不是7的原因是,避免反复横跳,转换过程也有开销。

  • hash函数的设计方法:定址法,数字分析法,折叠法,随机数法和除留余数法等等。

image-20221107193432749

(30条消息) 来吧!一文彻底搞定哈希表!_庆哥Java的博客-CSDN博客