数据结构散列表,再探链表keyhash

从上面的章节不难发现,无论散列函数怎么构建总会发生碰撞,最多只能降低碰撞概率,但是并不能杜绝碰撞,因此如何解决碰撞问题成了散列重中之重。

01、碰撞解决方案

下面我们一起来看看几种碰撞处理策略。

1、链式法

链式法的核心思想可以理解为把碰撞的key直接放到一个大的集合中;

我们先来回顾一下何为碰撞,碰撞就是两个不同的key,通过散列函数计算出相同的散列值。

为什么发生碰撞就会出问题呢?因为散列表本质上是数组,数组一个下标只能对应一个值,如果key1和key2发生碰撞,意味着key2对应的value2会把key1对应的value1覆盖掉,这就会导致了数据丢失。

想解决这个问题我直观想法是如果发生碰撞时value2不是覆盖value1,而是两者同时存储下来,是不是这个问题就解决了呢?

答案是肯定的,但是里面还有很多细节要处理。如一个数组元素里怎么再存放多个元素呢?对于发生碰撞的key如何查找呢?

首先一个数组元素里怎么存放多个元素?其实方法有很多,比如数组元素中直接存放一个数组,比如数组中存放一个链表表头指向一个链表等等。

在散列表中,每个数组元素所在的位置,我们称为“桶”或者“槽”,而每个桶(槽)又对应一条链表,发生碰撞的所有key都放到相同的桶对应的链表中,这种碰撞处理策略称为链式法。

当存取元素时分两步,第一步先找到key所在的桶,第二步再在桶所对应的链表中存取元素。

这个方案是非常简单实用的,而且因为链表节点是动态申请这也大大提升了空间利用率。

2、开放寻址法

开放寻址法的核心思想可以理解为当发生冲突时,如果当前散列位置已被使用就按某种方式继续探测下一个可以用的散列位置。

而某种方式继续探测具体是指当发生冲突时,则在当前散列值基础上再加上指定的步长并判断当前散列位置是否可用,如果不可用则重复此步骤。

因此开放寻址法可以概况为:hash_value=(hash(key)+step(i))%m,1≤i≤m-1

如上图当如果数组中浅绿代表空地址,浅橙色表示已经被占用,当传入key4时,经过散列函数计算出所在数组索引应该为6,而此时索引6已经被占用,因此继续往后探测,索引8已经被占用,继续往后探测,索引0已经被占用,继续往后探测,索引1空闲,存入value4。

而根据不同的步长生成规则,又可以分成以下几种探测方法:线性探测法、平方探测法、双重散列探测法、随机探测法等等

(1)线性探测法

线性探测法是通过在散列表中线性探测下一个可用位置来解决碰撞。

当发生碰撞时,则按顺序探测下一个元素位置,直至查找到可用的散列地址或者排查完全表。因此当探查到表尾地址时,并不是结束探测而是回到表首继续探测,直至探测到起始探测位置。

其公式可表示为:hash_value=(hash(key)+step)%m,1≤step≤m-1

优点:1、实现简单;2、效率较高,在负载因子较低时特别更为突出。

(2)平方探测法

平方探测法是通过使用平方增量来解决哈希冲突,从而有效地分散元素。

如果说线性探测法每次探测的步长是step,那么平方探测法的探测步长则是step的平方。

其公式可表示为:hash_value=(hash(key)+step^2)%m,1≤step≤m-1

与线性探测法相比,平方探测法主要优势在于增量平方数使得探测位置分布更广,位置也就更分散,从而减少元素的聚焦现象,从而提高查找效率。因此平方探测法在处理碰撞时通常优于线性探测法,当然选择哪种方法应根据具体应用场景和性能要求来决定。

优点:减少聚集现象,元素分布均匀。

缺点:1、仍可能存在二次聚集现象(即某些位置可能因为探测规则而频繁被访问)。2、可能无法探测到所有位置,在负载因子较高时尤为突出。

(3)双重散列探测法

双重散列探测法是使用两个散列函数来决定探测序列,从而更有效地分散冲突。也就是当发生碰撞时,会使用第二个散列函数来生成增量从而确定下一个要查找的位置。

其公式可表示为:hash_value=(hash(key)+i*hash2(key))%m,1≤i≤m-1

优点:1、减少聚集现象,效率高,探测路径较为随机。2、可以探测到所有位置,理论上避免了聚集问题。

缺点:实现相对复杂,且需要选择合适的第二个散列函数。

(4)随机探测法

随机探测法是通过随机选择下一个探测位置来解决冲突。也就是说当发生碰撞时,确定查找的下一个位置的增量式一个随机数。

其公式可表示为:hash_value=(hash(key)+r)%m,1≤r≤m-1

优点:1、大幅减少聚集现象,位置探测随机性强。2可以有效分散元素,降低碰撞影响。

缺点:1、随机性可能导致性能不稳定,尤其是在负载因子较高时。2、难以预测和调试。

总结

3、再散列法

再散列法的核心思想可用理解为对现有散列表进行扩容并重新计算现有元素位置。

我们先来回忆一个概念负载因子,负载因子式用来衡量散列表填充程度,通过散列表已存储的元素个数除以散列表的大小计算可得。

负载因子过大会导致一些列问题,首先会加大碰撞概率,碰撞概率增大又会导致处理碰撞成本增加,进而导致性能下降。同时也可能导致内存碎片化使用率不高,等等问题。

而负载因子就是触发再散列的时机,当负载因子超过某个阈值(一般是0.75)时,进行再散列。

而再散列的难点在于如何处理新老数据,是当触发再散列时一次性迁移所有老数据到新散列表中,还是分批次迁移老数据直至所有老数据迁移完成为止?

而分批迁移实现上会更复杂一些,要处理好新老数据共存时的查找、插入、删除等操作。

整体思路如下:

(1)当负载因子到达设定的阈值,则重新申请新的内存空间,不进行老数据迁移;

(2)当有新数据要插入时,将新数据插入至新的内存空间中,并取出一个老数据插入到新的内存空间中;

(3)重复步骤(2)直至所有老数据都迁移至新的内存空间为止;

(4)当在新老数据共存进行查找时,可用先在老的空间进行查找,如果不存在再到新空间中查找。

THE END
1.逻辑回归实际应用例子mob64ca140d2323的技术博客Estimator:估计器是一种算法,用于DataFrame转换。例如,学习算法是一种估计器,它训练一个DataFrame并生成一个模型。 pipeline:管道将多个变压器和估计器链接在一起,以指定一个ML工作流。 二、spark ml实现 尝试用spark ml实现广告点击预测,训练和测试数据使用Kaggle Avazu CTR 比赛的样例数据,下载地址:https://www.kaghttps://blog.51cto.com/u_16213670/12852502
2.“信息安全”课程习题及参考答案网络信息安全doc什么是序列密码和分组密码? 序列密码是一种对明文中的单个位(有时对字节)运算的算法。分组密码是把明文信息分割成块结构,逐块予以加密和解密。块的长度由算法设计者预先确定。 简述公开密钥密码机制的原理和特点? 公开密钥密码体制是使用具有两个密钥的编码解码算法,加密和解密的能力是分开的; http://read.cucdc.com/cw/62655/104021.html
3.软考系统架构设计师教程学习笔记第十一章系统架构设计师认证的方法归结为3大类:知道什么、拥有什么、是什么。 是什么,是一种基于生物识别技术的认证。 1.用户名和口令认证,三种简单的认证方式:明文传送、单向散列、单向散列函数和随机函数。 2.使用令牌认证,密钥存储于令牌中。 令牌是一个可以加密存储并运行相应加密算法的设备,完成对用户必须拥有某物的验证。 https://www.educity.cn/rk/1776400.html
4.信息安全技术(第4期,进行中)超星尔雅学习通网课答案3、【填空题】PGP加密系统中采用的公钥加密算法是 算法,用于生成报文摘要的单向散列函数算法(Hash算法)可以采用 算法,对称加密算法可以采用 算法。4、【填空题】PGP加密系统不仅可以对邮件进行加密,还可以对 、 等进行加密。5、【简答题】在使用PGP加密系统时,如果没有对导入的其他人的公钥进行签名并赋予完全信任http://xuzhou.ehqc.cn/html/07_12.html
5.PGP简介pgp是一种电子邮件安全方案,它一般采用()作为标准算法PGP是用一个128位的二进制数作为“邮件文摘”的,用来产生它的算法叫MD5(message digest 5)。 MD5是一种单向散列算法,它不像CRC校验码,很难找到一份替代的邮件与原件具有同样的MD5特征值。 回到数字签名上来,甲用自己的私匙将上述的128位的特征值加密,附加在邮件后,再用乙的公匙将整个邮件加密。这样这份密文被https://blog.csdn.net/bekars/article/details/677963
6.什么是NSA的信息安全三属性散列值 也可以使用散列算法验证完整性。本质上,消息的散列被生成并附加到消息的末尾。接收方计算他们收到的消息的哈希值,并将其与收到的哈希值进行比较。如果在传输过程中发生了变化,哈希值将不匹配。 在许多情况下,散列是一种可接受的完整性检查。但是,如果拦截方希望故意更改消息并且消息未加密,则哈希是无效的。https://www.360doc.cn/article/68899713_1026866534.html
7.数据加密技术网络通信11篇(全文)PGP把公开密钥体系的密钥管理方便性和对称密钥体系的高速度相结合,一方面使用DEA算法对数据进行加密,而另一方面使用RSA算法对DEA的密钥进行加密。这样,两类体制的算法结合在一起实现加密功能,突出了各自的优点,是较理想的安全快捷加密软件工具。 五、结束语https://www.99xueshu.com/w/ikeytnago16b.html
8.Android签名与校验过程详解数字签名:靠加密解密算法进行支撑 单向散列算法 MD5,SHA 非对称密钥算法:RSA 数字签名算法:DSA(Digital Signture Algorithm) 数字签名标准:DSS(DigitalSinature Standard) 使用私钥对摘要进行加密,即为数字签名! 下图描述了数字签名的大概流程,具体流程比这个稍微复杂一些。 非对称数字签名算法 :RSA 签名具有的特性:https://www.pianshen.com/article/42981323170/
9.数据加密算法有哪些?哪个更适合我?PGP全称为Pretty Good Privacy,即优良保密协议,通常采用IDEA的散列算法作为加密与验证之用,是1991年Phil Zimmerman在基于RSA加密算法所创建的一种算法,和其他加密算法不同,PGP无需服务器、证书或发件人和收件人之间的任何其他类型共享秘密来使用加密技术。 https://www.fanyedu.com/content/4465.html
10.网络安全之密码技术3、根据加密过程中是否使用随机数可以将加密体制分为概率加密体制和确定性加密体制。 如果在加密算法中使用了除明文和加密密钥以外的随机数,则称它为概率加密体制;相反,如果加密算法除了明文和加密密钥外没有使用任何的随机数,则称为确定性加密体制。显然,对于确定性加密体制来说,一个明文在相同密钥下的密文是确定的https://www.zhuanzhi.ai/document/85caa599181acc1c953eee769da130f0
11.PGP算法及其原理PGP(Pretty Good Privacy)是一个混合加密算法。由一个对称加密算法,一个非对称加密算法,一个单向hash散列算法,一个随机数生成器组成。 工作流程 认证算法 1. 发送方创建消息 2. 发送方创建消息的160位散列码 3. 发送方用私钥对散列码进行加密,附加到消息上 https://www.jianshu.com/p/fb726679d52f
12.Pythonhashlib模块详情pythonSHA:secure Hash Algorithm 安全散列算法1,是一种密码散列算法,SHA-1可以生成摘要消息为40位的16进制即160位(20字节)的散列值 用途:TSL、SSL、PGP、SSH等协议中广泛使用 3. hashlib 属性方法 hashlib 模块相关属性 hashlib 构造对象相关的属性 hashlib 模块相关方法目前可以支持主流hash算法。 https://www.jb51.net/article/230710.htm
13.SHA安全散列算法腾讯云开发者社区文章目录一、报文鉴别二、鉴别分类三、报文鉴别四、密码散列函数五、MD5 算法六、SHA-1 安全散列算法七、MAC 报文鉴别码一、报文鉴别 --- 计算机网络安全措施 : ① 针对被动攻击散列值 被截获 , 截获者无法伪造出一个 对应的输入值 ( 明文 / 发送数据 ) ; 密https://cloud.tencent.com.cn/developer/information/SHA%E5%AE%89%E5%85%A8%E6%95%A3%E5%88%97%E7%AE%97%E6%B3%95
14.PGPPGP是用一个128位的二进制数作为“邮件文摘”的,用来产生它的算法叫MD5(message digest 5)。 MD5是一种单向散列算法,它不像CRC校验码,很难找到一份替代的邮件与原件具有同样的MD5特征值。 回到数字签名上来,甲用自己的私匙将上述的128位的特征值加密,附加在邮件后,再用乙的公匙将整个邮件加密。这样这份密文被https://baike.sogou.com/v453393.htm
15.你知道PGP和GPG的区别吗?GPG=Gnu Privacy Guard. Gnu隐私保护。它 是在OpenPGP基础上更新了的。为了完全免费,所以不再使用IDEA散列算法。它是使用NIST 和 AES 高级加密的软件。 二,PGP 和GPG 之间的区别是什么? 1. 名字区别。PGP= Pretty Good Privacy。GPG= Gnu Privacy Guard. https://developer.aliyun.com/article/1432461
16.加密协议PGP和GPG的区别,你知道么?PGP使用RSA软件和IDEA加密算法。 GPG=Gnu Privacy Guard. Gnu隐私保护。它?是在OpenPGP基础上更新了的。为了完全免费,所以不再使用IDEA散列算法。它是使用NIST和AES高级加密的软件。 二、PGP和GPG之间的区别是什么? 名字区别。PGP=PrettyGoodPrivacy。GPG=GnuPrivacyGuard. http://www.51testing.com/html/18/n-6993418.html?nomobile=1
17.什么是安全电子邮件端到端的安全电子邮件技术保证邮件从发出到被接收的整个过程中,内容无法修改,并且不可否认。PGP和S/MIME是目前两种成熟的端到端安全电子邮件标准。 PGP(Pretty Good Privacy)被广泛采用,通过单向散列算法对邮件内容进行签名,以保证信件内容无法被修改,使用公钥和私钥技术保证邮件内容保密且不可否认。发信人与收信人的http://help.cstnet.cn/zhishiku/zhishiku_aqyj.html