- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
动态hash思想
本文将介绍三种动态hash方法。
散列是一个非常有用的、非常基础的数据结构,在数据的查找方面尤其重要,应用的非常广泛。然而,任何事物都有两面性,散列也存在缺点,即数据的局部集中性会使散列的性能急剧下降,且越集中,性能越低。
数据集中,即搜索键在通过hash函数运算后,得到同一个结果,指向同一个桶,这时便产生了数据冲突。
通常解决数据冲突的方法有:拉链法(open hashing)和开地址法(open addressing)。拉链法我们用的非常多,即存在冲突时,简单的将元素链在当前桶的最后元素的尾部。开放地址法有线性探测再散列、二次线性探测再散列、再hash等方法。
以上介绍的解决冲突的方法,存在一个前提:hash表(又称散列表)的桶的数目保持不变,即hash表在初始化时指定一个数,以后在使用的过程中,只允许在其中添加、删除、查找元素等操作,而不允许改变桶的数目。
在实际的应用中,当hash表较小,元素个数不多时,采用以上方法完全可以应付。但是,一旦元素较多,或数据存在一定的偏斜性(数据集中分布在某个桶上)时,以上方法不足以解决这一问题。我们引入一种称之为动态散列的方法:在hash表的元素增长的同时,动态的调整hash桶的数目。
动态hash不需要对hash表中所有元素进行再次插入操作(重组),而是在原来基础上,进行动态的桶扩展。有多种方法可以实现:多hash表、可扩展的动态散列和线性散列,下面分别介绍之,方法由简单到复杂。
多hash表:顾名思义,即采用多个hash表的方式扩展原hash表。这种方式不复杂,且理解起来也较简单,是三者中最简单的一种。
通常,当一个hash表冲突较多时,需要考虑采用动态hash方式,来减小后续操作继续在该桶上的冲突,减轻该桶负担,最简单且最容易想到的就是采用多hash表的方式。如下图,有一个简单的hash结构:
0
0
6
1
2
7
8
13
18
23
9
4
a桶
b桶
d桶
e桶
c桶
Hash表个数n
1
图:多hash表初始状态
简单起见,假定(1)hash函数采用模5,即hash(i)=i%5;(2)每个桶中最多只可放4个元素。
在以上基础上,向hash表中插入5,由于桶a存在空闲,直接存入。接着向hash表插入值3,由于d桶中已满,无空闲位置,此时在建立一个hash表,结果如下图
0
0
5
66
1
26
7
86
13
96
4
18
23
3
2
Hash表个数n
图:插入元素5和3之后的hash表结构
图:
通过图示,一目了然,原来的一个hash表,变为现在的两个hash表。如需要,该“分裂”可继续进行。
需要注意的是:采用这种方式,多个hash表公用一个hash函数,且目录项的个数也随之增多,分别指向对应的桶。实际上,这时存在两个不同的目录项,分别指向各自的桶。
执行插入、查找、删除操作时,均需先求得hash值x。插入时,得到当前的hash表的个数,并分别取得各个目录项的x位置上的目录项,若其中某个项指向的桶存在空闲位置,则插入之。同时,在插入时,可保持多个hash表在某个目录项上桶中元素的个数近似相等。若不存在空闲位置,则简单的进行“分裂”,新建一个hash表,如上图所示。
查找时,由于某个记录值可能存在当前hash结构的多个表中,因此需同时在多个目录项的同一位置上进行查找操作,等待所有的查找结束后,方可判定该元素是否存在。由于该种结构需进行多次查找,当表元素非常多时,为提高效率,在多处理器上可采用多线程,并发执行查找操作。
删除操作,与上述过程基本类似,不赘述。需要注意的是,若删除操作导致某个hash表元素为空,这时可将该表从结构中剔除。
这种解决hash冲突的方法,优点是:思想简单,实现起来也不复杂。由于一存在桶满的情况就另分配一个hash表,因此占用内存空间较大;当数据较集中时,桶利用率会很低。
可扩展的动态散列:引入一个仅存储桶指针的目录数组,用翻倍的目录项数来取代翻倍的桶的数目,且每次只分裂有溢出的桶,从而减小翻倍的代价。这里需要几个参数:H表示hash函数、D表示全局位深度、L表示桶的局部深度。还是来看个例子,参照这个图,你会更明了。
4*
4*
2
12*
32*
16*
1*
2
5*
21*
10*
2
15*
2
7*
10*
2
00
01
10
11
全局位深度D
局部位深度L
目录
a桶
b桶
c桶
d桶
图:简单的示意图
图:
图中,每个目录项有一个指向桶的指针,为介绍方便,我们假定(1)每个桶只可存放4个元素;(2)每个桶中存放的元素j*表示H(i)=j,为方便起见,只图示了j的值,并以’ *’标注。当前有4个目录项,目录项的编号从00~11,用两个位即可表示所有的目录项,因此全局位深度
文档评论(0)