双散列

我们将要考察的最后一个冲突解决方法是双散列(double hashing)。对于双散列一种流行的选择是,意思是说冲突解决函数中又有一个对应X的散列函数,并在距离等处探测。选择不好将会是灾难性的,例如插入99,对于通常的选择将不起作用,当冲突发生时,冲突函数的值都将是0值,解决不了冲突。因此函数一定不要算得0值。

诸如这样的函数将起到良好的作用,其中R为小于tableSize的素数。使用双散列时保证表的大小为素数时重要的,假设选取R为7,表大小为10。若想把23插入表中而与某个数发生冲突之后,,且该表大小为10,因此我们只有一个备选位置,而这个位置已经使用了。因此,如果表的大小不是素数,那么备选单元就有可能提前用完。然而如果双散列正确实现,则模拟表明,预期的探测次数几乎和随机冲突解决方法的情形相同。双散列理论上很有吸引力,不过相比之下平方探测不需要使用第二个散列函数,从而在实践中可能更简单并且更快。

再散列

对于使用平方探测的开放定址散列法,如果表的元素填得太满,那么操作的运行时间将开始消耗过程,且Insert操作可能失败。这可能发生在有太多的移动和插入混合的场合。此时一种解决方法是建立另外一个大约两倍大(原表两倍大的下一个素数)的表(而且使用一个相关的新散列函数,扫描整个原始散列表,计算每个(未删除的)元素的新散列值并将其插入到表中。整个操作就叫作再散列(rehashing),显然这是一种非常昂贵的操作,其运行时间为,因为有N个元素要再散列而表的大小约为2N,不过由于不是经常发生,因此实际效果没有那么差。

添加到每个插入上的花费基本上是一个常数开销(这是新表要做成老表约两倍大的原因,这样一次插入就不会存在很多冲突增加运行时间从而基本上是常数开销)。如果这种数据结构是程序的一部分,那么其效果是不显著的。另一方面,如果再散列作为交互系统的一部分运行,那么其插入引起再散列的不幸的用户将会感到速度减慢。

再散列可以用平方探测以多种方法实现。一种做法是只要表填满一半就再散列。另一种极端的方法是只有当插入失败时才再散列。第三种方法是途中(middle-of-the-road)策略:当表到达某一个装填因子时进行再散列。由于随着装填因子的增加,表的性能的确有下降,因此,以好的截止手段实现的第三种策略,可能是最好的策略。

再散列还可以用在其他的数据结构中。例如队列,再散列的实现很简单,

如下:

HashTable ReHash(HashTable h)
{if (h == NULL)return NULL;int i;int oldSize = h->tableSize;Cell* oldCells = h->theCells;h = InitializeTable(2 * oldSize);for (i = 0; i < oldSize; i++){if (oldCells[i].info == Legitimate)Insert(h, oldCells[i].element);}free(oldCells);return h;
}

可扩散列

最后来讨论数据量太大以至于装不进主存的情况,此时主要考虑的是检索数据所需的磁盘存取次数。

我们假设在任意时刻有N个记录要存储,N的值随时间变化。此外最多可把M个记录放入一个磁盘区块。现在设M=4。

如果使用开放定址散列法或分离链接散列法,那么主要的问题在于,在一次Find操作期间,冲突可能引起多个区块被考察,甚至对于理想分布的散列表也在所难免。不仅如此,当表变得过满的时候,必须执行执行代价巨大的再散列这一步,它需要次磁盘访问。

一种聪明的选择叫作可扩散列(extendible hashing),它允许用两次磁盘访问执行一次Find。插入操作也需要很少的磁盘访问。

我们知道B树具有深度。随着M的增加,B树的深度降低。理论上我们可以选择使得B树深度为1的M。此时在第一次以后的任何Find都将花费一次磁盘访问,因为据推测根节点可能存在主存中。这种方法的问题在于分支系数(branching factor)太高,以至于为了确定数据在哪片树叶上要进行大量的处理工作。如果运行这一步的时间可以减缩,那么我们就有一个实际的方案,这正是可扩散列使用的策略。

现在假设我们的数据由几个6位二进制数组成。“树”的根含有四个指针,它们由这些数据的前两位确定。每片树叶有最多M=4个元素。现在举个例子,碰巧这里每片树叶中数据的前两位都是相同的。为了更正式用D代表根所使用的位数,有时称其为目录(directory),于是,目录中的项数为为树叶L所有元素共有的最高位的位数。将依赖于特定的树叶,因此

设欲插入关键字100100。它将进入第三片树叶,但是第三片树叶已经满了,没有空间存放它。因此我们将这片树叶分裂成两片树叶,它们由前三位确定。这需要将目录的大小增加到3,变化如图所示

目录大小变为3,项也随之变为8项,因为多加一位有0有1两种,所以每一项变成两项。

如果插入关键字000000,那么第一片树叶就要分裂,生成=3的两片树叶。由于D=3,故在目录中所作的唯一变化是000和001指针的更新,而目录位数不增加。

这个非常简单的方法提供了对大型数据库Insert操作和Find操作的快速存取时间。这里还有一些重要细节我们尚未考虑。

散列表--双散列、再散列与可扩散列相关推荐

  1. 散列——再散列与双散列(C++)

    双散列: 原理很朴素.既然第一个哈希值会发生冲突,那再来一个哈希值不就好了? 比如,现在有两个哈希函数,分别记作Hash1(X)与Hash2(X),其中,X为关键字. 假如现在我们得到的第一个哈希值H ...

  2. 散列查找 散列表(哈希表)

    哈希表的平均查找长度是()的函数. A.哈希表的长度 B.哈希表的装填因子 C.哈希函数 D.表中元素的多少 装填因子 = 关键字个数 / 表长 符号表:是 "名字(Name)–属性(Att ...

  3. 二次探测再散列举例_二次探测散列法

    展开全部 二次再散e68a84e8a2ad3231313335323631343130323136353331333431366365列法是指第一次散列产生哈希地址冲突,为了解决冲突,采用另外的散列函 ...

  4. 散列表、散列函数和散列冲突以及应用场景(一文看懂)

    1.什么是散列表? 散列表(HashTable,也叫哈希表):由数组扩展而来,是根据键(Key)直接访问在内存存储位置的数据结构. 实现原理是:通过散列函数(也叫哈希函数)将元素的键(key)映射为数 ...

  5. 字典:散列表、散列字典、关键字列表、集合与结构体

    字典 散列表和散列字典都实现了Dict的行为.Keyword模块也基本实现了,不同之处在于它支持重复键. Eunm.into可以将一种类型的收集映射转化成另一种. defmodule Sum dode ...

  6. 【数据结构与算法】散列表

    一.散列表的由来? 1.散列表来源于数组,它借助散列函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性. 2.需要存储在散列表中的数据我们称为键,将键转化为数组下标的方法称为散 ...

  7. [数据结构][Python]python实现散列表

    散列表的实现常常叫做散列(hashing).散列仅支持INSERT,SEARCH和DELETE操作,都是在常数平均时间执行的.需要元素间任何排序信息的操作将不会得到有效的支持. 散列表是普通数组概念的 ...

  8. 数据结构与算法(七)—— 散列表结构及其实现和应用

    注:本篇内容参考了<Java常用算法手册>.<大话数据结构>和<算法导论(第三版)>三本书籍.并参考了百度百科. 本人水平有限,文中如有错误或其它不妥之处,欢迎大家 ...

  9. JavaScript数据结构之字典和散列表

    JavaScript数据结构之字典和散列表 集合.字典和散列表可以存储不重复的值.在字典中,我们用[键,值]的形式来存储数据.在散列表中也是一样(也是以[键,值]对的形式来存储数据) 字典 集合表示一 ...

最新文章

  1. vue:虚拟dom的实现
  2. 2020牛客多校G[并查集的两种思想,按秩合并+路径压缩]
  3. python爬取文章保存_爬取博主所有文章并保存到本地(.txt版)--python3.6
  4. SDUT _2117 数据结构实验之链表二:逆序建立链表
  5. 小Z的袜子(hose)
  6. java深拷贝和浅拷贝介绍
  7. gridview DataFormatString
  8. spock框架_Spock VW:编写自定义的Spock框架扩展
  9. 【转】ABP源码分析四十二:ZERO的身份认证
  10. jq父级绑定事件的意义_用jQuery.delegate()将事件绑定在父元素上面
  11. 企业如何实际使用 Docker
  12. php rabbitmq延迟队列示例
  13. 智能语音识别app下载-智能语音识别app安卓版下载v2.2 - 非凡软件站
  14. Linux下制作虚拟软盘镜像
  15. VirtualBox使用教程
  16. getDerivedStateFromProps填坑
  17. UCB CS285课程笔记目录
  18. 推荐一些学习类APP
  19. 云和恩墨数据库MogDB荣获2021年度IT168最佳创新产品奖
  20. 【Matlab】时间序列周期性分析

热门文章

  1. 阿里云客服联系方式汇总
  2. marvin java_Java开源图像处理框架Marvin介绍
  3. 自动批量配音软件V2.6 附参数和使用教程
  4. 蜻蜓FM回应恶意代码事件 音频行业仍将现721格局
  5. net::ERR_FILE_NOT_FOUND报错
  6. Windows 11 预览版来了?
  7. vue 服务器代码更新 浏览器页面不更新
  8. listview下拉刷新上拉加载扩展(三)-仿最新版美团外卖
  9. java初中学历_20岁学java初中学历
  10. ORACLE怎么读英语,oracle是什么意思_oracle怎么读_oracle翻译_用法_发音_词组_同反义词_神示所-新东方在线英语词典...