算法设计与分析——散列表/哈希表(Hash Table):完全散列

分类目录:《算法设计与分析》总目录
相关文章:
·散列表/哈希表(Hash Table)(一):基础知识
·散列表/哈希表(Hash Table)(二):直接寻址表
·散列表/哈希表(Hash Table)(三):散列表原理
·散列表/哈希表(Hash Table)(四):散列函数
·散列表/哈希表(Hash Table)(五):开放寻址法
·散列表/哈希表(Hash Table)(六):完全散列


使用散列技术通常是个好的选择,不仅是因为它有优异的平均情况性能,而且当关键字集合是静态时,散列技术也能提供出色的最坏情况性能。所谓静态,就是指一旦各关键字存入表中,关键字集合就不再变化了。一些应用存在着天然的静态关键字集合,如程序设计语言中的保留字集合,或者CD-ROM上的文件名集合。一种散列方法称为完全散列,如果该方法进行查找时,能在最坏情况下用 O ( 1 ) O(1) O(1)次访存完成。

我们采用两级的散列方法来设计完全散列方案,在每级上都使用全域散列。下图描述了该方法:
完全散列
第一级与带链接的散列表基本上是一样的:利用从某一全域散列函数簇中仔细选出的一个散列函数 h h h,将 n n n个关键字散列到 m m m个槽中。

然而,我们采用了一个较小的二次散列表 S j S_j Sj及相关的散列函数 h j h_j hj,而不是将散列到槽 j j j中的所有关键字建立一个链表。利用精心选择的散列函数 h j h_j hj,可以确保在第二级上不出现冲突。

但是,为了确保在第二级上不出现冲突,需要让散列表 S j S_j Sj的大小 m j m_j mj为散列到槽 j j j中的关键字数 n j n_j nj的平方。尽管 m m m n n n的这种二次依赖看上去可能使得总体存储需求很大,但我们会在后面说明,通过适当地选择第一级散列函数,可以将预期使用的总体存储空间限制为 O ( n ) O(n) O(n)

我们采用的散列函数是《算法设计与分析——散列表[哈希表](四):散列函数》中的全域散列函数类。第一级散列函数选自类 m m m,其中 p p p是一个比任何关键字值都要大的素数。那些散列到槽 j j j中的关键字通过利用一个从类 H p , m j \mathcal{H}_{p,m_j} Hp,mj中选出的散列函数 h j h_j hj,被重新散列到一个大小为 m j m_j mj的二次散列表 S j S_j Sj中。

下面分两步进行。首先,要确定如何才能保证第二级散列表中不发生冲突。其次,要说明使用总体存储空间的期望数为 O ( n ) O(n) O(n),这里包括主散列表和所有的二级散列表所占的空间。

如果从一个全域散列函数类中随机选出散列函数 h h h,将 n n n个关键字存储在一个大小为 m = n 2 m=n^2 m=n2的散列表中,那么表中出现冲突的概率小于 1 2 \frac{1}{2} 21

上述引用所描述的情形(即 m = n 2 m=n^2 m=n2)中,对于一个从 H \mathcal{H} H中随机选出的散列函数 h h h,较有可能不发生冲突。给定待散列的包含 n n n个关键字的集合 K K K(注意 K K K是静态的),只需几次随机的尝试,就能比较容易地找出一个没有冲突的散列函数 h h h

但当 n n n比较大时,一个大小为 m = n 2 m=n^2 m=n2的散列表还是很大的。因此,我们采用两级散列方法,并利用上述的做法,对每个槽中的关键字仅进行一次散列。一个外层的(或称为第一级的)散列函数 h h h用于将各关键字散列到 m = n m=n m=n个槽中。那么,如果有 n j n_j nj个关键字被散列到了槽 j j j中,可以用一个大小为 m j = n j 2 m_j=n_j^2 mj=nj2的二级散列表 S S S来提供无冲突的常数时间查找。

现在再来看看如何确保所用总体存储空间为 O ( n ) O(n) O(n)的问题。由于第 j j j个二级散列表的大小 m m m以所存储的关键字数 n n n的平方方式增长,因而存在着这样一种风险,即所需的总体存储空间量可能会很大。

如果第一级散列表的大小为 m = n m=n m=n,则用于存储主散列表、大小为 m j m_j mj的二级散列表,以及用于存储二次散列函数 h j h_j hj的参数 a j a_j aj b j b_j bj的存储空间总量为 O ( n ) O(n) O(n)

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

von Neumann

您的赞赏是我创作最大的动力~

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

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

打赏作者

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

抵扣说明:

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

余额充值