散列表(Hash Table)

散列表也称作为哈希表,它是一个动态表,然而它支持字典的操作,因为它的存储一个值,需要相应的键。在查找一个值时,也需要一个键。最基本的操作就是:insert, search以及delete。散列表作为一个动态表,它的性能表现的异常好。甚至在合理的假设条件下,它的操作只需要 O(1) 的代价。
本章主要内容:
这里写图片描述

1. 直接地址法(Direct-address tables)

当我们的关键字全域 U 比较小时,直接寻址就显得十分有效,直接上图:
这里写图片描述
上图展示了,全域的大小就是表的大小,同时关键字只映射一个值。这个明显的一个缺点时,当我们的全域变得很大时,它就很会浪费空间。

2. 哈希函数(Hash function)

哈希函数的主要作用就是将我们的关键字映射成一个在哈希表中的位置。最基本的方法有除留余法,乘法散列,以及全域散列。在实际过程中我们用的更是复杂的哈希函数(如RS,JS),在这里我们只介绍全域散列。

全域散列

因为在实际当中,可能一个散列函数,会把许多关键子散列成同一个值,而实际当中最有效的方法就是,我们在一组不错的散列列函数,选择1个散列函数作为我们这 1 次的散列函数。如果又有一个关键字要散列的话,我们就从散列函数组中重新随机话选择1个散列函数进行散列。这样选中同一个的散列函数的可能性就会比较低,从而散列到同一个位置的可能性也十分低。因此它的平均性能也十分突出。

3. 碰撞冲突

碰撞冲突,主要是因为我们在散列的时候可能散列到同一个值,这样就会形成冲突。在这里我们主要有种方法解决冲突。链接法,再哈希以及开放定址法。开放地址法还有线性探查,二次探查以及双重散列。

链接法

直接上图更容易清楚:
这里写图片描述
从途中我们可以看出,当我们有散列值冲突的时候,我们就需要用一个双向链表将冲突的具有相同的散列值得关键字链在一起。这样就能够很好的解决冲突。
我们来分析其一般的性能:假设表长为 m , 共有n个关键要散列。则我们可以算出表中每一个位置对应的元素长度: Θ(1+α) (其中的O(1)是用来计算哈希值的。
个人觉得其有一个不好的点:就是对于频繁删除和添加的操作则,要不断频繁的创造节点和删除节点,可能会消耗大量的时间,不过它的实现过程十分简单而且解决冲突的效果也是十分不错。

再哈希

当我们关键字在 hash 函数 h1 映射的时候发生了碰撞,然后选择另一个 hash 函数 h2,h3,...hn 直至没有冲突。这样做的缺点很明显, 1 是需要大量的hash函数,另外 1 个就是要不断的计算hash值。

开放定址法(open addressing)

线性探测(linear probing)

假设表长为 m , 则散列函数如下:

h(k,i)=(h(k)+i)mod m,    i=0,1,2,...,m1

给定一个关键字 k , 先用hash函数 h() 算出散列地址,探测这个位置是否冲突,如果冲突,则将地址 +1 直到没有冲突的位置。

二次探测(quadratic probing)

直接看散列函数:

h(k,i)=(h(k)+c1i+c2i2)mod m,    i=0,1,...,m1

和线性探测不同的时探测函数用的是二次函数。

双重散列(double hashing)

直接看散列函数:

h(k,i)=(h1(k)+ih2(k))mod m,    i=0,1,...,m1

3 种开放定址法对比

通过图我们可以很容易看出他们之间的区别
1线性探测
这里写图片描述
2
这里写图片描述
3
这里写图片描述
从上面我们可以看出,双重散列更接近均匀散列。线性探测,可能导致查找的平均时间变长,而二次探测为了能够充分利用散列表,则 c1,c2,m 要受到限制。

均匀散列分析

定理3.1 [1]

给定一个装载因子 (loadfactor) α=n/m<1 的开放寻址散列表,则对于一次不成功的探查次数至多为 1/(1α)

定理3.2 [2]

对于一个装载因子为 α<1 的开放寻址散列表,一次从成功查找中的探查期望数至多为

1αln11α

证明略,当 nm=12 时,探查期望小于 1.387 , 而当 nm=0.9 时, 探查期望小于2.559. [3]

4. 源码

本人在clion IDE中实现的 , 下载请转此下载:http://download.csdn.net/detail/yzf0011/9772449

5. 感谢

本文是基于《算法导论》写的,最主要的是有本人大量的心得体会,感谢《算法导论》的那些作者Thomas H.Cormen、Charles E.Leiserson等 人。如果有错误的请留言,不甚感激。谢谢。

6. 参考

[1]《算法导论》Thomas H.Cormen、Charles E.Leiserson等 第三版第11章 “散列表” p155
[2]《算法导论》Thomas H.Cormen、Charles E.Leiserson等 第三版第11章 “散列表” p155
[3]《算法导论》Thomas H.Cormen、Charles E.Leiserson等 第三版第11章 “散列表” p155

转载,请注明

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值