Hash 函数之冲突解决

接上一篇《数据结构检索(查找)之入土攻略(二)》:https://blog.csdn.net/wydyd110/article/details/82144549

目录

5 冲突排解

5.1 开放地址法(Open Addressing)

5.1.1线性探测法(Linear Probing)

5.1.2 平方探测法(Quadratic Probing)

5.1.3  双散列探测法(Double Hashing)

5.2 链地址法

6 散列表的性能分析


5 冲突排解

      目前,世间还没有十全十美的散列函数,还不能做到完全避免冲突,就跟我们无法保证每天都大便通畅。既然冲突不能避免,那么当务之急是要考虑如何处理它。

      

      

5.1 开放地址法(Open Addressing)

当你看上了一个女神,却发现她有男朋友了,这时候你要怎么办?换一个女神经去喜欢啊,天涯何处无芳草,何必单恋一枝花呢?这其实就是开放地址法对于冲突的处理方式。对了,通知大家一下,亦菲的地下lover是我。

开放定址法:一旦产生了冲突(该地址已有其它元素),就按某种规则去寻找另一空地址。

5.1.1线性探测法(Linear Probing)

线性探测法:以增量序列 1,2,……,(TableSize -1)循环试探下一个存储地址。

47 / 11 = 4 ......3                       7 / 11 = 0......7                             其他同理

分析:

成功平均查找长度(查找表中关键词的平均查找比较次数,冲突次数加1)

ASLs = (1+7+1+1+2+1+4+2+4)/ 9 = 23/9 ≈ 2.56

(11一找就找到了,所以查找了1次,其他同理)


不成功平均查找长度 (不在散列表中的关键词的平均查找次数)

ASLu = (3+2+1+2+1+1+1+9+8+7+6)/ 11 = 41/11 ≈ 3.73

(当要查找的关键词的散列值为0,按照线性探测法,需要查找比较3次,才能确定该关键词不在散列表中)

(当要查找的关键词的散列值为1,按照线性探测法,需要查找比较2次,才能确定该关键词不在散列表中)

(当要查找的关键词的散列值为2,按照线性探测法,需要查找比较1次,才能确定该关键词不在散列表中)

  其他同理

分析:

(表中8-25省略不写)

ASLs:表中关键词的平均查找比较次数
ASL s= (1+1+1+1+1+2+5+3)/ 8 = 15/8 ≈ 1.87


ASLu:不在散列表中的关键词的平均查找次数(不成功)
根据H(key)值分为26种情况:H值为0,1,2,…,25
ASL u= (9+8+7+6+5+4+3+2+1*18)/ 26 = 62/26 ≈ 2.38

5.1.2 平方探测法(Quadratic Probing)

                          

5.1.3  双散列探测法(Double Hashing)

(引用自《大话数据结构》)

(引用自张铭的《数据结构与算法》)

5.1.4 再散列(Rehashing)

5.2 链地址法

随便问十个程序员他的女朋友是谁,有九个回答是新垣结衣,由此可以意淫出一个新恒结衣身后吊着一长串屌丝程序员的画面。大家一起手拉手共同守护同一个老婆也是可以的对吧。这就引出了另一种冲突解决方法:

分离链接法:将相应位置上冲突的所有关键词存储在同一个单链表中。

不管多累,为了老婆要努力学下去哦。

(引用自《大话数据结构》)

6 散列表的性能分析

7 Hash 算法应用场景

7.1 请求的负载均衡(如 nginx 的 ip_hash 策略)

Nginx 的  IP_hash  策略可以在客户端  ip  不变的情况下,将其发出的请求始终路由到同⼀个⽬标服务器上,实现会话粘滞,避免处理 session  共享问题。
 
问: 如果没有 IP_hash 策略,那么如何实现会话粘滞?
 
可以维护⼀张映射表,存储客户端IP或者 sessionid 与具体⽬标服务器的映射关系 <ip,tomcat1>
缺点
1 )在客户端很多的情况下,映射表⾮常⼤,浪费内存空间
2 )客户端上下线,⽬标服务器上下线,都会导致重新维护映射表,映射表维护成本很⼤
 
如果使⽤哈希算法,我们可以对  ip  地址或者  sessionid  进⾏计算哈希值,哈希值与服务器数量进⾏取模运算,得到的值就是当前请求应该被路由到的服务器编号,如此,同⼀个客户端 ip 发送过来的请求就可以路由到同⼀个⽬标服务器,实现会话粘滞。
 

7.2 分布式存储

以分布式内存数据库  Redis  为例 , 集群中有  redis1 redis2 redis3 三台  Redis  服务器。那么, 在进⾏数据存储时 ,<key1,value1>数据存储到哪个服务器当中呢  ?针对  key  进⾏  hash  处理
hash(key1)%3=index, 使⽤余数 index 锁定存储的具体服务器节点。
 

8 普通 Hash 算法存在的问题

 

普通 Hash 算法存在⼀个问题,以 ip_hash  为例,假定下载⽤户  ip  固定没有发⽣改变,现在  tomcat3  出现了问题,down  机了,服务器数量由  个变为了  个,之前所有的求模都需要重新计算。

如果在真实⽣产情况下,后台服务器很多台,客户端也有很多,那么影响是很⼤的,缩容和扩容都会存在这样的问题,⼤量⽤户的请求会被路由到其他的⽬标服务器处理,⽤户在原来服务器中的会话都会丢失。

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值