哈希

197 阅读1分钟

哈希算法

index = hash%length length 一般取素数,以使得求模运算出来的冲突更少(可以提前计算出素数表存起来)
将 key 转换为固定长度数组下标,存取<key,value>。

解决冲突常见方法

当一个索引位置已经存取了某个值,后续通过计算又落到该索引位置时,产生存取冲突,解决方法有:

  1. 开放地址: 产生冲突时,使用线性探测,向后移动 n 个位置。该方式缺点是容易引发元素聚集。
  2. 再哈希Rehash:发生冲突时,使用第二个,第三个 hash 函数计算地址(比如取第 n 位),直到无冲突
  3. 链表: 新加的数据更可能是"热数据",所以将新增加的元素插入链表头部 在编程语言层面,GoLangC++ unordered_map 使用链表结构. Java HashMap 实现默认也是链表,不同的是当 bucket 内链表长度超过 8 的时候转换成红黑树(目的是加快查找) C#使用的是再哈希方式,一次冲突再换一个,直到找到有空位的地方存储。 Python dic{}采取开放地址

装载因子

a = 元素个数/hash数组大小,a 在 0.6~0.9 之间,一般取 0.75. 即当存取元素的数组接近装载满时,重新生成一个新的更大数组并将旧数据导入。