服务器哈希冲突怎么解决

  

本篇内容主要讲解“服务器哈希冲突怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“服务器哈希冲突怎么解决”吧!

一、哈希表概述

哈希表的哈希函数输入一个键,并向返回一个哈希表的索引。可能的键的集合很大,但是哈希函数值的集合只是表的大小。

哈希函数的其他用途包括密码系统、消息摘要系统、数字签名系统,为了使这些应用程序按预期工作,冲突的概率必须非常低,因此需要一个具有非常大的可能值集合的散列函数。

密码系统:给定用户密码,操作系统计算其散列,并将其与存储在文件中的该用户的散列进行比较。(不要让密码很容易被猜出散列到相同的值)。

消息摘要系统:给定重要消息,计算其散列,并将其与消息本身分开发布。希望检查消息有效性的读者也可以使用相同的算法计算其散列,并与发布的散列进行比较。(不要希望伪造消息很容易,仍然得到相同的散列)。

这些应用的流行哈希函数算法有:

  • md5 : 2^128个值(找一个冲突键,需要哈希大约2 ^ 64个值)

  • sha-1:2^160个值(找一个冲突键,需要大约2^80个值)

二、哈希冲突

来看一个简单的实例吧,假设采用hash函数:H(K)=K mod M,插入这些值:217、701、19、30、145

H(K)= 217 % 7 = 0

H(K)= 701 % 7 = 1

H(K)= 19 % 7 = 2

H(K)= 30 % 7 = 2

H(K)= 145 % 7 = 5

服务器哈希冲突怎么解决

上面实例很明显 19 和 30 就发生冲突了。

三、冲突解决策略

除非您要进行“完美的散列”,否则必须具有冲突解决策略,才能处理表中的冲突。
同时,该策略必须允许查找,插入和删除正确运行的操作!

冲突解决技术可以分为两类:开散列方法( open hashing,也称为拉链法,separate chaining )和闭散列方法( closed hashing,也称为开地址方法,open addressing )。这两种方法的不同之处在于:开散列法把发生冲突的关键码存储在散列表主表之外,而闭散列法把发生冲突的关键码存储在表中另一个槽内。

下面介绍业内比较流行的hash冲突解决策略:

  • 线性探测(Linear probing)

  • 双重哈希(Double hashing)

  • 随机散列(Random hashing)

  • 分离链接(Separate chaining)

上面线性探测、双重哈希、随机散列都是闭散列法,而分离链接则是开散列法。

1、线性探测(Linear probing)

插入一个值

使用散列函数H(K)在大小为M的表中插入密钥K时:

  1. 设置 indx=H(K)

  2. 如果表位置indx已经包含密钥,则无需插入它。Over

  3. 否则,如果表位置indx为空,则在其中插入键。Over

  4. 其他碰撞。设置 indx=(indx + 1)mod M.

  5. 如果 indx==H(K),则表已满!就只能做哈希表的扩容了

因此,线性探测基本上是在发生碰撞时对空槽进行线性搜索。

优点:易于实施;总是找到一个位置(如果有);当表不是很满时,平均情况下的性能非常好。

缺点:表的相邻插槽中会形成“集群”或“集群”键;当这些簇填满整个阵列的大部分时,性能会严重下降,因为探针序列执行的工作实际上是对大部分阵列的穷举搜索。

简单例子

如哈希表大小M=7, 哈希函数:H(K)=K mod M。插入这些值:701, 145, 217, 19, 13, 749

H(K)= 701 % 7 = 1

H(K)= 145 % 7 = 5

H(K)= 217 % 7 = 0

H(K)= 19 % 7 = 2

H(K)= 13 % 7 = 1(冲突) --> 2(已经有值) --> 3(插入位置3)

H(K)= 749 % 7 = 2(冲突) --> 3(已经有值) --> 4(插入位置4)

可见,如果哈希表如果不是很大,随着数据插入,冲突也会组件发生,探针遍历次数将会逐渐变低,检索过程也就成为穷举。

服务器哈希冲突怎么解决