hash表冲突处理方法
为提高hash表查找性能,除了考虑选择合适的hash表表长和完美的hash函数外,还必须考虑hash表处理冲突的能力。当hash函数对两个不同的数据项产生了相同的hash值时,冲突就产生了。对于冲突的处理,通常采用的方法可以分为三类:
(1)线性再散列法,简单的按顺序遍历hash表,寻找下一个可用的槽;
(2)非线性再散列法,计算一个新的hash值;
(3)外部拉链法,将hash表中的每个槽当作具有相同hash值的数据项所组成链表的头部,hash表将发生冲突的项添加到同一个链表中。
下面对这三种方法分别介绍。
1.线性再散列法
线性再散列法是形式最简单的处理冲突的方法。插入元素时,如果发生冲突,算法会简单的遍历hash表,直到找到表中的下一个空槽,并将该元素放入该槽中。查找元素时,首先散列值所指向的槽,如果没有找到匹配,则继续遍历hash表,直到:(1)找到相应的元素;(2)找到一个空槽(指示查找的元素不存在);(3)整个hash表遍历完毕(指示该元素不存在并且hash表是满的)。下表显示了以线性再散列法将{89,18,49,58,69}5个元素插入hash表的过程。(hash函数为:hash(X)=X mod 10;hash表长一般用素数,这里为了说明方便取表长为10)
第一次冲突发生在插入关键字49时,它被放在下一个空闲地址,即地址0。关键字58依次和18,89,49发生冲突,试选三次之后才找到一个空单元。对69的冲突用类似的方法处理。从以上过程可以看出,只要表中有空闲单元,总可以找到,但这里选择步长为1,将会在hash表中产生聚集,即:即使hash表相对较空,还是会在某些区域形成一些区块,这些区块中的任何活动都将设计更大的步长。但如果以5或更大的值作为步长,可以迅速地从拥挤区域移开,从而减少聚集现象的发生。事实上,只要hash表长和检查槽的步长是互质的,那么表中的每个槽都会被检查到。
线性再散列法有两个缺点:第一,不能从表中删除元素,因为相应的单元可能已经引起过冲突,元素绕过它存到了别处,例如,如果我们删除了18,那么其他的元素都会找不到。如果确实需要删除,可以采用懒惰删除的方法。第二,当表被填满时性能下降明显。
2.非线性再散列法
线性再散列法是从冲突位置开始,采用一个步长以顺序方式遍历hash表,来查找一个可用的槽,从上面的讨论可以看出,它容易产生聚集现象。非线性再散列法可以避免遍历散列表,它会计算一个新的hash值,并通过它跳转到表中一个完全不同的部分。它的思想就是:通过跳转到表中不同的部分,从而避免相似值的聚集,如果再散列函数跳转到的槽已经被占用了,则继续执行新一轮的再散列和跳转。
例如,还是上面的例子,如果再散列函数是hash(X)=R-(X mod R),其中R为小于hash表长的素数,如果我们选择R=7,则下表显示了插入与前面相同的关键字的结果。
第一个冲突发生在49被插入的时候, hash(49)=7-0=7,故49被插入到位置6。Hash(58)=7-2=5,于是58被插入到位置3。最后69产生冲突,从而被插入到距离为hash(69)=7-6=1的地方。
非线性再散列法也有不能从表中删除元素的缺点。
无论是使用线性再散列法还是非线性再散列法,只有在散列表不会接近填满的情况下,才能使用再散列。当散列表的负载因子增大时,再散列所花费的时间也会显著增加。通过以上讨论可以看出,再散列方法适用于表负载较低并且不太可能执行删除操作的情况。
3.外部拉链法
外部拉链法是将hash表看作是一个链表数组,表中的每个槽要不为空,要不指向hash到该槽的表项的链表。可以通过把元素添加到链表中来解决冲突。同样,可以通过从链表中删除元素来执行删除操作。因此,解决冲突的代价不会超过向链表中添加一个节点,不需要执行再散列。在再散列中,表项的最大数量是由表中槽的原始数量确定的,与之不同的是,外部拉链法可以容纳的元素于将在内存中存放的元素一样多。
外部拉链法的原则是:hash表的大小一般与预料的元素个数差不多。
假设有一个表长为10的hash表,给出10个关键字为前10个自然数的平方,hash函数为hash(X)=X mod 10,下图就是对应的外部拉链法的hash表。
外部拉链法的平均查找时间是对链表的查找时间加上1,这个1是最初的定位hash表槽。外部拉链法的缺点是:它需要稍微多一些的空间来实现,因为添加任何元素都需要添加指向节点的指针,并且每次探查也要花费稍微多一点的时间,因为它需要间接引用指针,而不是直接访问元素。由于今天的内存成本很低并且可以使用非常快的CPU,所以这些缺点都是微不足道的。因此,实际使用hash表时,一般都是使用拉链法来解决hash冲突。
【from:http://blog.csdn.net/qll125596718/article/details/7028322】
hash表冲突处理方法相关推荐
- 解决哈希(hash)冲突的方法
解决哈希(hash)冲突的方法 当关键字值域远大于哈希表的长度,而且事先并不知道关键字的具体取值时.冲突就难免会发生.另外,当关键字的实际取值大于哈希表的长度时,而且表中已装满了记录,如果插入一个新记 ...
- 教你几招HASH表查找的方法
摘要:根据设定的哈希函数 H(key) 和所选中的处理冲突的方法,将一组关键字映象到一个有限的.地址连续的地址集 (区间) 上,并以关键字在地址集中的"象"作为相应记录在表中的存储 ...
- hash表冲突太多如何平滑地进行rehash操作
Linux内核中大量使用了hash表,然而我们知道,hash表这个数据结构的查找效率和数据的规模是强相关的: hash表总是处在链表和完美hash的某种中间状态. 其中,hash冲突是我们必然要面对的 ...
- 【数据结构笔记40】哈希表冲突处理方法:开放地址法(线性探测、平方探测、双散列、再散列),分离链接法
本次笔记内容: 11.3.1 开放定址法 11.3.2 线性探测 11.3.3 线性探测-字符串的例子 11.3.4 平方探测法 11.3.5 平方探测的实现 11.3.6 分离链接法 文章目录 冲突 ...
- Hash算法冲突解决方法分析
就不自己写了,直接贴下吧 看了ConcurrentHashMap的实现, 使用的是拉链法. 虽然我们不希望发生冲突,但实际上发生冲突的可能性仍是存在的.当关键字值域远大于哈希表的长度,而且事先并不知道 ...
- 用链表和数组实现HASH表,几种碰撞冲突解决方法
Hash算法中要解决一个碰撞冲突的办法,后文中描述了几种解决方法.下面代码中用的是链式地址法,就是用链表和数组实现HASH表. he/*hash table max size*/ #define HA ...
- HashMap解决hash冲突的方法
HashMap解决hash冲突的方法 博客分类: jvm虚拟机 在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap ...
- Hash算法解决冲突的方法
Hash算法解决冲突的方法一般有以下几种常用的解决方法 1, 开放定址法: 所谓的开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入 公式为 ...
- Hash函数与算法、哈希查找、哈希冲突解决方法总结
Hash哈希知识点导航 1.基本概念 2. 哈希函数 2.1 直接寻址法 2.2 数字分析法 2.3 平方取中法 2.4 折叠法 2.5 随机数法 2.6 除留余数法 3. 哈 ...
最新文章
- mysql低级知识坑
- [转]一次.NET Web应用程序安装包的制作经历:Sql数据库安装的3种方式 配置IIS及Web.Config文件...
- 【转】 GetProcAddress()用法
- 同一类的不同对象,在调用相同的成员函数时,入口地址是相同的
- ubuntu下hbase的伪分布式安装与配置
- n个数里找出前m个数(或者 从10亿个浮点数中找出最大的1万个)
- 2022十大科技趋势
- python 点_Python中的方括号和点符号有什么区别?
- 《三国演义》社交网络数据分析:最重要的一号人物竟是……
- 同步、异步、阻塞、非阻塞IO
- 分配销售组织 - 分销渠道 - 工厂
- java实习面试题整理
- 磨刀不误砍柴工(四)-IDEA常用快捷键
- 学而思编程python拓展版_学而思网校【2019-寒】少儿编程直播班-scratch Level 1上(零基础)...
- 如何制作一个优秀的个人网站?
- 视频怎么做GIF表情包?教你一键生成gif动图
- 概率论---古典概型
- PLUG AND PLAY LANGUAGE MODELS: A SIMPLE APPROACH TO CONTROL LEDTEXT(PPLM):代码深入理解(二)—PPLM_Discrim
- 【JAVA程序设计】(C00046)javaweb图书借阅管理系统
- 深入浅出带你学习报错注入
热门文章
- 精简Linux文件路径
- 解决dom4j java.lang.NoClassDefFoundError: org/jaxen/JaxenException
- 51CTO首页改版上线 欢迎大家拍砖!
- Eclipse调试Java程序技巧
- 将一个包含有2层数据分组的表输出到EXCEL表里,并分组统计
- 基于【CentOS-7+ Ambari 2.7.0 + HDP 3.0】搭建HAWQ数据仓库02 ——使用ambari-server安装HDP...
- Kafka源码分析-序列3 -Producer -Java NIO(Reactor VS Peactor)
- input中checked复选框进行单选
- 云际阔,总相连——Let's Connect!
- ESLint使用文档