散列中对load factory(填装因子)的选择和重要。(合理分布,尽可能少的冲突)
散列函数越是随机,越是没有规律,就越好
1.除余法
key%M=key&(M-1);
选择2的K次方很好计算,但是容易发生冲突
除余法可能会存在的一些问题:
1.0除余任何数都是0,即确定性,而散列应均匀分布
2.邻接性。即相邻的两个数在散列表上的分布必然是相邻的
2.MAD法
散列冲突:
不同值的hashcode可能相同,因此就会发生冲突。可以用数组存储,但是前提得知道所需数组的长度,否则会造成效率不高,因此往往用链表更好。(封闭定址,所有数都被固定好了存储在哪一个key的链表上,它们的物理位置可能毫无联系,无法使用cache)
也可以使用固定的数组进行线性探测,若冲突了就往后移一格,一直到没有冲突为止。由此,最多可以存储数组的length个元素。(线性探测+懒删除好用)(开放定址,散列表占用的空间在地址上始终是连续的)
开放定址的线性探测可能会造成许多重复的比较,因为它是相邻的比较,能不能跨步比较呢?于是便有了平方探测,但是你会发现平方探测有的位置可能永远探测不到,换句话说就有可能在几个地方一直重复。数学验证可知M个位置前M/2个位置存储的是互异的,平且后M/2个位置基本用不到
于是便有了双平方探测,即一下正向探测,一下反向探测,相互颠倒。但是重复检测便会发现,当M取值不是素数且是4k+3的倍数时,左右取值会发生重复,因此双平方探测适用于4k+3类型的素数。