引言
哈希表是一种组合的数据结构,它通常的实现方式是数组加链表,或者数组加红黑树。哈希表是一种牺牲空间去换取时间的数据结构,需要在空间与时间上有取舍,哈希表是时间和空间之间的平衡。哈希表的核心是哈希函数,哈希表最关键的问题哈希冲突也是取决于哈希函数的设计。
哈希函数
1、什么是哈希函数
哈希函数是一种将“键”转换为“索引”的逻辑规则。它的设计好坏对哈希表的性能影响巨大。优良的哈希函数能够最大程度的减少哈希冲突,使得哈希表中的元素分布得尽可能的均匀,离散程度更大,这样哈希表就会性能优越;较差的哈希函数设计,带来的可能是一场灾难,哈希冲突严重,空间利用率低,时间复杂度呈线性恶化,造成频繁的扩容操作。
2、哈希函数的设计
对于哈希函数的设计,以下举了一些简单的例子,都基本类型转换成整型处理,并不是唯一的方法,仅供参考。以下简单列了几条设计原则。
- 一致性:如果a == b,则hash(a) == hash(b)
- 高效性:哈希函数计算高效简便
- 均匀行:哈希值均匀分布
1、整型
-
小范围正整数可直接使用
-
小范围负整数进行偏移
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kYn18R6l-1658297349288)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/88876490695c4177a50f98cee34326a8~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]
- 大整数可以与一个合适的素数取模
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-syvFKJSS-1658297349291)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d34fecfc78424d49af0ba7ede6528f2f~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]
说明:上图(左)与一个不合适的合数取模,获得的索引冲突严重,不可取;而上图(右)与一个质数取模,明显获得的索引分布更均匀,离散程度更好。
2、字符串型
- 字符串型转换成整型处理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E7jaVlkZ-1658297349291)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/503cbb47c0e64b428fdc3d11b2acd20f~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]
说明:其中B为一个常数,M为一个合适的质数。上图将一个字符串型加入一些规则映射成了一个整型。
3、代码实现简单hash函数
// 1.将字符串转成比较大的数字:hashCode
// 2.将大的数字hashCode压缩到数组分为(大小)之内
function hashFunc(str, size) {
// 1.定义hashCoed变量
let hashCode = 0
// 2.霍纳算法,来计算hashCode的值
for (var i = 0; i <