之前的两篇文章多次提到哈希冲突,这里再解释一下。

所谓哈希冲突,就是两个key值经过哈希函数计算以后得到了相同的哈希值,而一个下标只能存放一个key,这就产生了哈希冲突,如果这个下标其中一个key先存着了,那另一个key就必须通过别的方法找到属于自己的存放位置。

产生了哈希冲突,我们就要解决。选择一个好的解决哈希冲突的方法,也是提高哈希表效率的关键。

开发定址法

为产生冲突的地址Hash(key)求得一个地址序列:

H0,H1,H2,...,Hn        1  <= n <= m - 1 其中m为表的大小

H0 = H(key) Hi = (H(key)+ di)% m  i=1,2,...n

形象地一句话来说,就是根据增量di不断地往后找可以存放的下标。

增量di可以有下面三种取值:

  1. 线性取值,1,2,3....这样,也就是从冲突位置不断往后找下一个可以存放的下标
  2. 二次取值,1,4,9....这样,也就是从冲突位置不断往后找x的二次方的下标,其中x从1开始线性增大
  3. 随机取值,di可以去任意随机值,随机找一个。

开放定制法有很明显的缺点

  • 元素不能删除
  • 当哈希表中元素越来越满时,效率明显下降

再哈希法

这其实就是一次哈希出来结果相同,再用另外的哈希函数来计算,直到不再产生相同的哈希值为止。这就要求我们设计不同的哈希函数,对程序的要求就更高一点,它也和开放定制法一样要保证装载因子,和开发定址法差不多其实。

哈希桶(拉链法)

每个下标中存的都是一个链表,相同哈希值的key直接往下标中的链表后面插入就行了

这种方法的特点是,表的大小和存储的数据数量差不多(大不了每个下标都只放一个节点,如果下标一样的都是放在同一下标的链表中,并没有占据新的下标) ,因此哈希桶的方法没有特别依赖于装载因子,哈希表块满时,它还是可以做到较好的效率,而开发定址法就需要保证装载因子。

当然,哈希桶法并不是万能的,也有它的缺点:

  • 它需要稍微多一点的空间来存放元素,因为还要有一个指向下一个节点的指针。
  • 每次探测也要花费较多的时间,因为它需要间接引用指针,而不是直接访问元素。

但其实,对于上面的缺点,对于现在的电脑来说并不会有太大的影响,所以这些缺点是微不足道的,所以实际使用哈希时,一般都是用哈希桶来解决冲突。

需要注意的是,哈希表也不是能让这个链表无限长的。打个比方,如果我所有的数据的哈希值都是一样,那么只会存在一个下标内,其余下标都没有用到,这就产生了一种极端情况。在这种情况下,我们要查找起来,就等于在一个链表中查找,它的查找效率是O(n),这显然违背了哈希表设计的思维。因此,在某一个链表或是几个链表的长度达到一定长度时,就需要对哈希表扩容,具体细节还是要看怎么设计了。

但是相比于开发定址法,它会发生扩容的频率就要小很多了,因为开发定址法还要保证自己的装填因子,所以它会更加频繁地扩容,所以就效率而言,拉链法还是要优于开发定址法。

哈希表(三)——哈希冲突相关推荐

  1. 三问了解哈希表和哈希冲突

    什么是哈希表? 哈希表也叫散列表,它是基于数组的.这间接带来了一个优点:查找的时间复杂度为 O(1).当然,它的插入时间复杂度也是 O(1).还有一个缺点:数组创建后扩容成本较高. 哈希表中有一个&q ...

  2. 哈希表及哈希冲突解决办法

    哈希表及哈希冲突解决办法 目录 什么是哈希表? 哈希表的数据结构 哈希冲突 哈希冲突解决办法 1. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直 ...

  3. 哈希表构造与处理冲突方法

    我们知道:哈希表是一个固定大小的数组,数组的每个元素是一个链表(单向或双向)的头指针.如果Key一样,则在一起,如果Key不一样,则不在一起.哈希表的查询是飞快的.因为它不需要从头搜索,它利用Key的 ...

  4. 哈希表(哈希函数和处理哈希冲突)_20230528

    哈希表(哈希函数和处理哈希冲突) 前言 关于哈希表的主题的小记原计划5月23日完成,由于本人新冠阳性,身体发烧乏力,周末感觉身体状况稍加恢复,赶紧打开电脑把本文完成,特别秉承"写是为了更好地 ...

  5. 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶

    文章目录 哈希 哈希(散列)函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列(开放地址法) 开散列(链地址法/拉链法) 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) ...

  6. 【数据结构】 哈希表查找—哈希函数、哈希冲突

    目录 一.哈希表的定义 二. 常用的哈希函数 三. 处理冲突的方法 四.哈希表的查找和性能分析

  7. 高级数据结构与算法 | 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶

    文章目录 哈希 哈希函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列的解决方法 开散列的解决方法 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) 插入 查找 删除 完整 ...

  8. 除留余数法构造哈希表_哈希表算法原理

    基本概念 哈希表(Hash Table)是一种根据关键字直接访问内存存储位置的数据结构.通过哈希表,数据元素的存放位置和数据元素的关键字之间建立起某种对应关系,建立这种对应关系的函数称为哈希函数. 哈 ...

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

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

  10. 大白话之哈希表和哈希算法

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

最新文章

  1. 多核处理器集成了神经处理单元
  2. codevs1316 文化之旅
  3. Vim技能修炼教程(16) - 浮点数计算函数
  4. 2020-07-02 CVPR2020 VL论文讨论(3) 笔记
  5. HashMap 1.7 死循环过程
  6. oracle 在数据库打开状态下进行备份时_下面描述不正确的是,Oracle数据库DBA面试题50道及答案_经典...
  7. quartz启动 mysql报错_quartz启动报错,本地是好的,部署到服务器就不行了,大神求助~~...
  8. dlib android 识别时间,android dlib调用
  9. 【并发】关于并发、超卖处理的思路
  10. UICollectionView 横向滑动停止的两种效果。
  11. 28岁自学Python转行靠谱吗?入行晚吗?
  12. linux上json文件格式化的查看工具jq
  13. Cashback [CodeForces - 940E]
  14. 将MNIST手写数字数据集导入NumPy数组(《深度学习入门:基于Python的理论与实现》实践笔记)
  15. android仿支付宝首页更多、应用编辑界面
  16. 【程序员的絮絮叨叨】分享我小半生的经历
  17. Matter实战教程-Silicon Labs EFR32:学习教程目录
  18. 你有什么样的职业规划?
  19. r星服务器维护公告,老主机下岗了!R星宣布12月16日关闭《GTA5》PS3、Xbox 360服务器...
  20. 怎样更优雅的检测僵尸好友

热门文章

  1. 电力拖动控制系统作业答案4
  2. 适用于火车头7.6的翻译插件-亲测10000篇文章稳定不报错
  3. google vr 入门之制作简易的VR播放器(三),真牛皮
  4. 科研资料|论文数模真的好难?那是你还不会Matlab!
  5. 极客DIY:只用两步教你制作一款可编程键盘 [译]
  6. 统计qq一天中每秒在线人数
  7. ADSP-21489的图形化编程详解(1:硬件的准备和软件环境的搭建)
  8. RPA下基层·社区医疗RPA丨居民医疗档案签约机器人
  9. Git之显示分支关系图(十五)
  10. Apache Kafka开发入门指南