我们知道,选定合适的哈希表 sizesizesize 值,将会使得元素尽可能均匀的分布在哈希表上,从而减少碰撞的发生和提升哈希表的空间利用率,相反,如果选择的哈希表 sizesizesize 值不恰当,将会增加碰撞和空间利用率下降
举一个极端的例子,如果原始的哈希表大小为 size=5size = 5size=5, 插入的数据元素分别为 45,111,122,78,14445, 111, 122, 78, 14445,111,122,78,144,且采用对 sizesizesize 取余来确定索引位置,此时数据恰好均匀分布在哈希表上,空间利用率为最理想的 100%100\%100%:
如果此时我们需要再加入一个新的元素 100100100,显然原哈希表需要扩容来容纳新元素,假设我们将哈希表大小增加到 size=11size = 11size=11,此时却发现数据全部碰撞在索引值为 index=1index = 1index=1 的位置:
我们尝试通过增加哈希表容量来减少碰撞发生的次数,可结果却事与愿违,因此 扩容时 sizesizesize 的选择非常关键,具体应该怎么选择有待分析…
实际上,很容构造出这样的一种情形:假设数据元素集合{ei∣ei mod m=i,i∈Zm}\{e_i|e_i\ mod\ m=i,i\in\mathbb{Z_m}\}{ei∣ei mod m=i,i∈Zm} 均匀的分布在 size=msize = msize=m 的哈希表的位置 0,1,2,⋯ ,m−10,1,2,\cdots,m-10,1,2,⋯,m−1 上,当扩容至 size=nsize = nsize=n 时,再不妨假设 gcd(m,n)=1(greatest common division)gcd(m,n)=1(greatest\ common\ division)gcd(m,n)=1(greatest common division) ,如果要使得 ei mod n=c(c为一个常数),∀i∈Zme_i\ mod\ n=c(c为一个常数),\forall{i\in \mathbb{Z_m}}ei mod n=c(c为一个常数),∀i∈Zm,即所有的数据元素集合在新哈希表下映射到同一个位置 ccc,利用中国剩余定理可以反解出 eie_iei:
{ei mod m=iei mod n=c\begin{cases}e_i\ mod\ m=i\cr e_i\ mod\ n = c\end{cases}{ei mod m=iei mod n=c
假设解为ei=((α1m⋅c+α2n⋅i)mod m⋅n)e_i = ((\alpha_1m\cdot c+\alpha_2n\cdot i)mod\ m\cdot n)ei=((α1m⋅c+α2n⋅i)mod m⋅n),且满足 α1m mod n=1,α2n mod m=1\alpha_1m\ mod\ n=1,\alpha_2n\ mod\ m=1α1m mod n=1,α2n mod m=1,即α1,α2\alpha_1,\alpha_2α1,α2 分别为在模 nnn 下 mmm 的乘法逆元和模 mmm 下 nnn 的乘法逆元,而求乘法逆元可以采用 Extended Euclidean algorithmExtended\ Euclidean \ algorithmExtended Euclidean algorithm(也即辗转相除法的扩展版本),也即如果数据元素eie_iei满足 ei=((α1m⋅c+α2n⋅i)mod m⋅n)e_i = ((\alpha_1m\cdot c+\alpha_2n\cdot i)mod\ m\cdot n)ei=((α1m⋅c+α2n⋅i)mod m⋅n) 的形式,且 gcd(m,n)=1gcd(m,n)=1gcd(m,n)=1,则会出现此极端情形
1982

被折叠的 条评论
为什么被折叠?



