散列

设计散列函数

  • 除余散列法

    设 hash(key)=key mod m,其中key表示被散列的关键字,而m则表示散列表的大小,mod则为取余操作。
    这是一种比较简单的散列函数,但简单并不意味着高效。当待散列的元素之间存在某种模式时,这种散列法会有相当糟糕的性能表现。

  • 乘法散列法

    设 hash(key)=floor(m×(A×key mod 1)),其中floor()表示对表达式进行下取整,A∈(0,1),m如上同样表示散列表的大小,且在这种方法中对m并无任何特殊的要求。
    [A×key mod 1]表示将key乘上某个在0~1之间的数并取乘积的小数部分,该表达式等价于A×key-floor(A×key)
    这里最重要的是A的值应该如何设定,Don•Knuth老大认为A=(√5-1)/2 [黄金分割点] 比较好。

  • 全域散列法(universal hashing)

    设 hasha,b(key)=(a×key+b) mod m,如同除余散列法中一样,m的值应为质数,而a∈{1,2,3,…,m-1},b∈{0,1,2,…,m-1}且a,b的值应在运行时动态确定。
    全域散列的基本思想是给出hash函数的基本“骨架”,而其中的某些参数通过运行时在指定范围内随机选取确定,从而实际上形成了一个函数簇。根据上述a,b的取值范围,我们知道这个函数簇中存在m×(m-1)个函数。因为对于同一个输入,每次执行时选取不同的参数将拥有不同的性能表现,因此设计的函数实际上独立于任意被散列的关键字。只有当一个相对糟糕的输入——即该输入不构成随机分布,遇到一个选取的相对糟糕的散列函数时,才将导致较差的性能,在多数情况下这类散列往往具有较好的运行时性能表现。

  • 完全散列法(perfect hashing)

开放寻址(open addressing)

  • 线性试探法

    设 hash(key, i)=(hash’(key)+i) mod m,其中 i=0,1,…,m-1,hash’为辅助散列函数在线性试探中,首次探查位置取决于hash’(key)的值,若发生碰撞,则接下来所探查的位hash’(key)-1>。因为散列表的大小为m,所以整个散列表总共提供m种不同的探查序列。并且由于线性试探使用连续探查的方式,因此随着散列表中元素的增加,所占用的槽逐渐呈连续分布状况,从而增加插入/搜索操作的期望时间。

  • 二次试探法
    设 hash(key,i)=(hash’(key)+c1i+c2i2) mod m,如上所述,i=0,1,…,m-1,hash’为辅助散列函数,c1,c2为辅助参数
    可以发现,线性试探法实际是二次试探的特殊情况,若取参数c1=1,c2=0,那么二次试探将“退化”为线性试探。同样的,整个探查序列也是由hash’(key)所决定的,因为虽然探查序列中各元素之间的增量[c1i+c2i2]不再以线性的方式进行,但对于每个元素来说,引导因子i总是以步长1的方式递增,这就导致所有元素的探查序列的增加方式是相同的,因此整个散列表同样提供m种不同的探查序列。但随着散列表中元素的增加,这种跳跃式的增量方式使得插入/搜索操作的运行时间受到的影响较小。

  • 双重试探法
    设 hash(key,i)=(hash’(key)+i×hash”(key)) mod m,其中i=0,1,…,m-1,hash’,hash”均为辅助散列函数 双重试探法的首个探查位置为hash’(key),当产生碰撞之后,接下来的探查位置为(hash’(key)+hash”(key)) mod m,因此我们发现在双重试探法中,不仅初始探查位置依赖于关键字key,探查序列中的增量hash”(key)同样依赖于关键字key,因而整个散列表提供了m2种不同的探查序列,较之于前两种开放寻址具备了更多的灵活性。这里还要注意的是应保证hash”(key)与m互质,若最大公约数p=gcd(m, hash”(key))>1,那么所能寻址的槽的个数为m/p小于m,使得对于一个关键字来说无法充分利用整个散列表。举例来说,若初始探查位置为1,偏移量为3,整个散列表大小为12,那么所能寻址的槽为<1, 4, 7, 10>,寻址个数为12/gcd(12,3)=4。

转自 http://blog.youkuaiyun.com/jn1158359135/article/details/7205688

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值