数据结构之二(续,高级hash)

问题:普通hash会导致对于特定的输入,其时间复杂度可以达到O(n)。为了解决这个问题,同快速排序的随机化一样,使用随机化算法来实现,从而可以使得复杂度不会依赖于输入,且性能能达到平均。

1.        全域hash(universal hashing)

全域hash:在执行的开始,随机地从一族hash函数中选择一个函数来执行hash。从而避免对特定输入导致的最差性能。

H为有限的一组散列函数,将关键字域U映射为{0,1,…,m-1}。这样的个函数组称为全域的

如果对任何一对不同的关键字k1,k2,H中使得h(k1)=h(k2)的函数的个数最多为|H|/m。

即,随机的从H中选择一个函数h,当关键字k1与k2不等时,发生冲突的概率不大于1/m。

这也是从集合{0,1,….,m-1}中随机、独立的选择时h(k1),和h(k2)发生冲突的概率。

 

如果h为H中的一个函数,h将n个关键字映射到一个m个槽且用链接法表示的hash表中。如果关键字k不在表中,则k被散列到的链表的长度期望至多为a(装载因子);如果k在表中,则k被散列到的链表的长度期望至多为1+a。

1.1.       全域hash的一种设计

设m为质数。将k表示为m进制的数k<k0,k1,k2,…,kr>,最大关键字为r+1位的m进制数。随机的选择一个a也表示为r位的m进制数a<a0,a1,a2,…,ar>。每一个ai都是随机选择的。由m进制的表示可知:ki,ai为0,m-1内的数。r是由最大关键字来决定的,m为hash表的槽数。

定义Ha(k) = (k0*a0+k1*a1+…+kr*ar)mode m,从而对所有的a,H中函数的个数为,m^(r+1)。

H为一族全域hash。

证明的思路:任取两个不同的键x,y;则其m进制表示中,至少有一位不同。如果碰撞,即h(x)=h(y)(mod m),由m为质数,因此这一位可以由其他的r位决定。从而使x,y碰撞的Ha的函数为m^r个(即|H|/m),因此为全域的。假设地0位为不同的,x0不等于y0,证明中并不要求对应的a0为0,因为x0-y0不为0,因此可以取倒数。从而a0可以由a1,…,ar决定。

1.2.       全域hash的另一种设计

选择足够大的质数p,使得p比任何k都大。Hash表的槽数m小于p。定义Zp为{0,1,…,p-1};Zp*为{1,..,p-1}。

对任何的a属于Zp*,b属于Zp,定义hash函数为

Ha,b(k)=((a*k+b) modp) mod m

所有的这些函数Hp,m将Zp映射到Zm。m不再要求为质数,可以为任意数。

H中函数的个数为p*(p-1),由a,b的选择决定。

H为一族全域hash。

证明的思路:对不同的关键字k,l由k,l不同,则mod p阶段的值也不同。不会有冲突。

r=(a*k+b) mod p

s=(a*l+b) mod p

Hash函数的取值对(a,b)有p*(p-1)种方式。对于每一对(a,b),都会产生不同的结果对(r,s),且r不等于s,因为给定r,s后,可以反解a,b。且(r,s),r不等于s的对的个数也为p*(p-1),因此(a,b)对于(r,s)对之间有1-1映射。

从而,r,s为随机选择的对时,不同k,l碰撞时r=s mod m。而对于给定的r,s可能取值为剩下的p-1种。其中满足s不等于r,且s=r mod m的s个数最多为:

[p/m] -1 <=((p+m-1)/m) -1 = (p-1)/m,从而在mod m的情况下,r与s冲突的概率小于

((p-1)/m)/(p-1)=1/m。

从而k与l冲突的概率<=1/m。从而H为全域的。

 

2.        完全hash。(perfect hashing)

Hash的好处在于有常数的期望性能

如果关键字的集合为静态的时,hash可以得到最差情况下的常数性能。

2.1.       静态是指:关键字集合一旦确定,则不再变化,不再有插入或删除。比如程序语言的关键字。

2.2.       完全hash:一种hash方法,在查找(不再有插入、删除)时,最坏的时间性能为O(1)的。槽数m与元素个数n同阶,即m=O(n)。

2.3.       方法

使用二级散列,每一级都使用全域hash。

第一层和普通hash链类似,不同在于,不是对每个槽位冲突的键建立链表,而是对每个槽位冲突的键建立另一个hash表(二级hash表),而第二层上的hash函数是经过挑选的,因此不会再有冲突。

第一层中可能会冲突,但是第二层后则不会有冲突。

第一层中,如果第i个槽有ni个键冲突,则第二层的hash表对应的链长mi=ni^2。

第二层会非常稀疏。

虽然第二层的大小为冲突数的平方级别,但是因为第一层为全域hash,因此总的存储空间也是O(n)级别的。

证明使用的引理

Ø  全域hash中随机选择的hash函数,将n个关键字存储到槽数为n^2的hash表中,碰撞的概率小于1/2

一对特定的键冲突的概率为1/m=1/(n^2),键冲突的组合有C(n,2)种情况(组合数),因此有键冲突的期望次数为C(n,2)/(n^2),小于1/2。

使用马尔可夫不等式即可得有键冲突的概率小于1/2。

从而对于第二层的hash函数,可以从全域hash中尝试选择一个特定的hash函数进行测试,使得不会有冲突发生。因为大部分都不会冲突,因此这种尝试不会太多。

当然如果只用一层hash来做实现不碰撞也可以,不过O(n^2)的hash表则比较大,浪费空间。所以才用二级散列的方法,在第二层使用这个技术。

Ø  空间为O(n)

第一层的槽数m=n。

对第二层的槽数使用期望(类似桶排序)。

第二层的期望空间为2*n.

利用马尔可夫不等式还可得,第二层空间超过4*n的概率小于1/2。

2.4.       应用

已知最常见的1000个词集合。任意给一个词,查询这个词是否为常见词。

K全域hash与安全认证。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值