哈希表

1.哈希表

哈希表(亦称为散列表)是一种根据关键码寻找值的数据映射结构。哈希表设计了映射关系f(key)=address,根据key计算存储地址address,以下图为例:

若想寻找余罪,可利用哈希函数:f(余罪)=s,所以可以在O(1)的时间内访问任意位置。

2.哈希冲突

哈希函数的映射可能会出现碰撞,即有多个元素被映射到同一个位置,出现哈希冲突,它与哈希函数的设计是正相关的,当哈希函数的随机性越大,产生哈希冲突的可能性越小。解决哈希冲突的方法主要有:

  • 链接法
  • 开放寻址法

2.1 链接法

链接法是将映射到同一个位置(称为、slot)的元素做成链表,假设元素个数为n,槽的个数为m,则定义装载因子α=n/m,也就是平均每个链表中元素的平均数量,在最坏情况下,哈希函数f()可能将所有的key映射到同一个槽中,则哈希表的查找时间为查找长度为n的链表,需要花费O(n)。

此时哈希函数的选择应遵循简单均匀散列假设:任何给定元素会等可能的映射到m个槽中的任意一个,并且与其他元素的位置所在无关。

则对于链接法解决哈希冲突的哈希表,一次成功查找和不成功的平均时间均为θ(1+α),其中θ(1)为计算哈希值和访问槽的时间。一般来说,当α=O(1)或n=O(m),即散列表的个数与元素个数成正比,查找哈希表的时间为O(1)。

此时哈希函数的构造:

2.1.1 除法散列法

f(key)=key mod m, 即为k/m取余数。注意不要选择过下的m,最好值为质数,不接近2的幂(此时哈希不会考虑到k的所有位)。

2.2.2 乘法散列法

f(key)=floor(m(kA mod 1)),0<A<1, floor为下取整,mod1为取小数部分。

2.2 开放寻址法

开放寻址法即系统的探查哈希表,知道找到一个空槽,此时α<1。该方法需要连续的探查哈希表,探查的顺序为probe sequence,写作:

<f(key,0),f(key,1),...,f(key,m-1)>,探查的过程为,初始化i=0,计算f(k,i),若该位置为空槽,将元素放入,否则I++,继续探查。

哈希函数的构造:

2.2.1 线性探查

f(key,i)=(f(key,0)+i) mod m,会遇到群集问题,即哈希表的某区间全部被占满。

2.2.2 二次哈希

f(key,i)=(f_1(key)+C*f_2(key)) mod m,以两种不同方式依赖于key,f_2(key)的值应与m大小互为素数,可以通过m取2的幂,或者m取素数,f_2(k)小于m。

2.2.3 完全哈希

先hash一次,找到空槽,再hash一次,找到二级hash表中的槽的位置,为保证二级hash表不冲突,需要让每个一级hash中槽中的二级hash表的大小为在这个槽中key的平方。

REFERENCE:

http://www.yixieshi.com/95421.html

算法导论(原书第三版)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

space_dandy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值