关于哈希表扩容的一点思考

我们知道,选定合适的哈希表 sizesizesize 值,将会使得元素尽可能均匀的分布在哈希表上,从而减少碰撞的发生和提升哈希表的空间利用率,相反,如果选择的哈希表 sizesizesize 值不恰当,将会增加碰撞和空间利用率下降
举一个极端的例子,如果原始的哈希表大小为 size=5size = 5size=5, 插入的数据元素分别为 45,111,122,78,14445, 111, 122, 78, 14445,111,122,78,144,且采用对 sizesizesize 取余来确定索引位置,此时数据恰好均匀分布在哈希表上,空间利用率为最理想的 100%100\%100%size=5
如果此时我们需要再加入一个新的元素 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}\}{eiei mod m=i,iZm} 均匀的分布在 size=msize = msize=m 的哈希表的位置 0,1,2,⋯ ,m−10,1,2,\cdots,m-10,1,2,,m1 上,当扩容至 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),iZm,即所有的数据元素集合在新哈希表下映射到同一个位置 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=((α1mc+α2ni)mod mn),且满足 α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 分别为在模 nnnmmm 的乘法逆元和模 mmmnnn 的乘法逆元,而求乘法逆元可以采用 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=((α1mc+α2ni)mod mn) 的形式,且 gcd(m,n)=1gcd(m,n)=1gcd(m,n)=1,则会出现此极端情形

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值