来源:趣谈编程作者:趣谈编程

Hash碰撞

慧能

一尘,国庆节过完了,还记得Hash函数吗?

当然记得了,Hash函数就是将任意长度的输入转化成固定长度的输出的一类函数

一尘

比如说我的输入是任意一个自然数(0,1,2,3...),而我要求经过一个函数后我的输出的数的范围要在0-9这样一个范围之间。

很容易想到,我们可以使用Hash函数:

其中key就是输入

在哈希表(散列表)里,Hash函数的作用就是将关键字Key转化为一个固定长度数组的下标,以便存取键值对

慧能

不错,还记得,那当多个键(key)经过Hash函数处理后落在了同一个位置时怎么办呢?

我记得上次师傅给我讲过链地址法

一尘

链地址法可看:神速Hash

开放地址法

慧能

记性不错,但还有一种方法叫开放地址法

哦?开放地址

一尘

所谓开放地址法就是发生冲突时在散列表(也就是数组里)里去寻找合适的位置存取对应的元素。

这个合适的位置该怎么找呢?

一尘

慧能

问的好,为师给你说说几种方法

线性探测法

最容易想到的就是当前位置冲突了,那我就去找相邻的下一个位置。

就拿放入元素举例吧,当你放入到下标为2的位置后,另一个键值对也落入了这个位置,那么它就向后依次加一寻找合适的位置,然后把放入进去。

我们把这种方法称作线性探测法,我们可以将Hash以及寻找位置的过程抽象成一个函数:

所以关键字要进行查找或者插入,首先看(hash1(key)+0)%7 位置是自己最终的位置吗?如果有冲突,就探测(查看)下一个位置:(hash1(key)+1)%7。依次进行

所谓探测,就是在插入的时候检查哪个位置可以插入,或者查找时查找哪个位置是要查找的键值对,本质就是探寻这个键值对最终的位置。

但是这样会有一个问题,就是随着键值对的增多,会在哈希表里形成连续的键值对

这样的话,当插入元素时,任意一个落入这个区间的元素都要一直探测到区间末尾,并且最终将自己加入到这个区间内。这样就会导致落在区间内的关键字Key要进行多次探测才能找到合适的位置,并且还会继续增大这个连续区间,使探测时间变得更长,这样的现象被称为“一次聚集(primary clustering)”

这可如何是好

一尘

平方探测法

慧能

我们可以在探测时不一个挨着一个地向后探测,我们可以跳跃着探测,这样就避免了一次聚集。

其实我们可以让它按照 i^2 的规律来跳跃探测

这样的话,元素就不会聚集在某一块区域了,我们把这种方法称为平方探测法

同样我们可以抽象成下面的函数:

其实可以扩展到更一般的形式:

虽然平方探测法解决了线性探测法的一次聚集,但是它也有一个小问题,就是关键字key散列到同一位置后探测时的路径是一样的。

这样对于许多落在同一位置的关键字而言,越是后面插入的元素,探测的时间就越长。

这种现象被称作“二次聚集(secondary clustering)”,其实这个在线性探测法里也有。

这种现象出现的原因是由于对于落在同一个位置的关键字我们采取了一个依赖 i 的函数(i或者i^2)来进行探测,它不会因为关键字的不同或其他因素而改变探测的路径。那么我们是不是可以让探测的方法依赖于关键字呢?

双散列

答案是可以的,我们可以再弄另外一个Hash函数,对落在同一个位置的关键字进行再次的Hash,探测的时候就用依赖这个Hash值去探测,比如我们可以使用下面的函数:

经过hash1的散列后,会定位到某一个地址,如果这个地址冲突,那么就按照1*hash2(key)、2*hash2(key)... 的偏移去探测合适的位置。

由于Hash2函数不同于Hash1,所以两个不同的关键字Hash1值和Hash2值同时相同的概率就会变得非常低。

这样就避免了二次聚集,但同时也付出了计算另一个散列函数Hash2的代价。

如果hash2(key)=0,那探测不就一直在原地不动,失效了吗?

一尘

慧能

聪明,所以hash2函数在选择的时候要避免这种情况。

原来解决冲突还有这种方法,看来国庆后要加倍努力了。

一尘

慧能

嗯嗯,看好你

其他相关:

一个故事讲完哈希洪荒攻击

推荐阅读

全部文章详细分类与整理(算法+数据结构+计算机基础)

玩公众号写文章一年多以来,我经历了被喷被拉黑被赞美,我酸了

有必要说一说即将到来的春招(经历+重要性+如何准备)

普普通通,我的三年大学

历经两个月,我的秋招之路结束了!

ds哈希查找--链地址法_Hash冲突之开放地址法相关推荐

  1. D. DS哈希查找与增补(表尾插入)

    目录 题目描述 思路分析 AC代码 题目描述 给出一个数据序列,建立哈希表,采用求余法作为哈希函数,模数为11,哈希冲突用链地址法和表尾插入 如果首次查找失败,就把数据插入到相应的位置中 实现哈希查找 ...

  2. ds哈希查找—二次探测再散列_大白话之哈希表和哈希算法

    哈希表概念 哈希表(散列表),是基于关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数(哈希函数 ...

  3. DS哈希查找--Trie树

    题目描述 Trie树又称单词查找树,是一种树形结构,如下图所示. 它是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点 ...

  4. SWUST OJ 1012: 哈希表(链地址法处理冲突)

    1012: 哈希表(链地址法处理冲突) 题目描述 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用链地址法.建立链表的时候采用尾插法. 输入 第一行为哈西表的长度m: 第二 ...

  5. 一文搞定哈希(六种构建、四种冲突解决方法、查找算法总结)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  6. lfu算法实现c语言_哈希查找算法(C语言实现)

    上一节介绍了有关哈希表及其构造过程的相关知识,本节将介绍如何利用哈希表实现查找操作.在哈希表中进行查找的操作同哈希表的构建过程类似,其具体实现思路为:对于给定的关键字 K,将其带入哈希函数中,求得与该 ...

  7. c语言求不成功查找长度的代码_哈希查找算法(C语言实现)

    上一节介绍了有关哈希表及其构造过程的相关知识,本节将介绍如何利用哈希表实现查找操作.在哈希表中进行查找的操作同哈希表的构建过程类似,其具体实现思路为:对于给定的关键字 K,将其带入哈希函数中,求得与该 ...

  8. Hash函数与算法、哈希查找、哈希冲突解决方法总结

    Hash哈希知识点导航 1.基本概念 2. 哈希函数   2.1 直接寻址法   2.2 数字分析法   2.3 平方取中法   2.4 折叠法   2.5 随机数法   2.6 除留余数法 3. 哈 ...

  9. 哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现

    哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现 参考文章: (1)哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现 (2)https://www. ...

  10. 哈希表_实现插入、删除、查找元素操作(链地址法解决冲突)

    这几天用在写代码(实际上是为了补作业)的时间明显比以前多了,在这过程中也 发现了自己由于前期的训练太少,导致很多基础的语法都不熟悉,有很长的时间都用在了debug上.很多问题写的时候记得,过后又忘了, ...

最新文章

  1. Java:Java和c的区别
  2. linux内核及其模块的查询,加载,卸载 lsusb等
  3. python 让异常名称显示出来
  4. python二维元素向量_详解python Numpy中求向量和矩阵的范数
  5. 四维偏序 CDQ套CDQ
  6. 在python中求小于100的所有合数_python输出100以内的质数与合数
  7. Java集合---面试题
  8. MySQL 基础理论面试题整理
  9. 《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》——第1章 异构建模 1.1语法、语义、语用...
  10. 计算机老掉线 路由器网络,路由器无线掉线怎么办?
  11. N沟道与P沟道增强型MOS管电压、原理、导通条件!
  12. java面试宝典及答案_最新Java面试宝典及答案
  13. MySQL基础~多表查询分类与SQL92和99语法如何实现内连接和外连接
  14. confluence 空间复制
  15. 奋斗吧,程序员——第五十四章 坐拥美人君莫笑,古来征战几人回
  16. 百度飞桨亮相2019 AIIA,四大领先技术剑指落地引开发者点赞
  17. linux环境中英文切换配置以及乱码问题
  18. Android Tab 控件的使用
  19. Android软件架构
  20. 2022年全球市场机器视觉频闪仪总体规模、主要生产商、主要地区、产品和应用细分研究报告

热门文章

  1. mysql中表示金钱的类型
  2. java创建一个单链表,接受输入的数据,并输出
  3. ORM数据库框架 LitePal SQLite MD
  4. Riverbed实现云内外的端到端可视化
  5. Linux中的cp命令老九门
  6. Spring配置bean文件的底层实现方式
  7. js对象深拷贝的简单实现
  8. linux malloc和free解析
  9. FRR BGP协议分析12 -- ZEBRA路由的处理1
  10. Internet路由之路由表查找算法概述-哈希/LC-Trie树/256-way-mtrie树