如何解决哈希冲突?

目录

1. 链接法

2. 开放寻址法

2.1. 线性探测

2.2. 二次探测

2.3. 双重哈希

3. 再哈希法

4. 哈希桶扩容

5.方法比较 

5.1. 链接法

5.2. 开放寻址法

5.3. 再哈希法

5.4. 哈希桶扩容

哈希表就是通过散列函数将键映射到定值,简单来说就是一个键对应一个值。

而通过散列函数映射时将两个键映射到了同一个值,即这两个键将被哈希表映射到同一个位置,这种情况就被称为哈希冲突。

解决哈希冲突通过有四种方法:

  • 链接法
  • 开放寻址法
  • 再哈希法
  • 哈希桶扩容

1. 链接法

每个哈希表的槽位维护一个链表或其他数据结构,当多个元素被哈希到同一个槽位时,它们会被放在这个槽位的链表中。查找时会遍历链表,插入时也会直接加到链表中。

假设我们有一个哈希表,哈希函数将键值映射到以下槽位:

  • 0: [5, 15]
  • 1: []
  • 2: [2]
  • 3: []
  • 4: [4]

当我们插入键值 5 和 15 时,它们都被映射到槽位 0。因此,它们会形成一个链表:

槽位 0: [5 -> 15]
槽位 1: []
槽位 2: [2]
槽位 3: []
槽位 4: [4]

2. 开放寻址法

当发生冲突时,算法会寻找下一个可用的槽位。常见的探查方式有线性探查、二次探查和双重哈希等。这种方法不使用额外的存储结构,而是在哈希表内部处理所有元素。开放寻址法的几种常见探测方法确实包括线性探测、二次探测和双重散列。以下是每种方法的详细说明和示例:

2.1. 线性探测

在发生冲突时,线性探测会逐个检查后续的槽位,直到找到一个空槽。例如:

假设哈希函数为 h(k) = k % 5

  • 插入 1 → 槽位 1(成功)
  • 插入 6 → 槽位 1(冲突),检查 2(成功)
  • 插入 11 → 槽位 1(冲突),2(冲突),3(成功)

最终哈希表:

槽位 0: []
槽位 1: [1]
槽位 2: [6]
槽位 3: [11]
槽位 4: []

2.2. 二次探测

二次探测在发生冲突时采用平方递增的方式查找空槽。例如:

哈希函数仍然假设是 h(k) = k % 5

  • 插入 1 → 槽位 1(成功)
  • 插入 6 → 槽位 1(冲突),检查 1^2 → 2(成功)
  • 插入 11 → 槽位 1(冲突),检查 1^2(冲突),2^2 → 4(成功)

最终哈希表:

槽位 0: []
槽位 1: [1]
槽位 2: []
槽位 3: []
槽位 4: [6]

2.3. 双重哈希

双重散列使用第二个哈希函数来决定步长,以解决冲突。例如:

假设第一个哈希函数 h1(k) = k % 5,第二个哈希函数 h2(k) = 1 + (k % 4)

  • 插入 1 → 槽位 1(成功)
  • 插入 6 → 槽位 1(冲突),步长 h2(6) = 1 + (6 % 4) = 3,检查 1 + 3 = 4(成功)
  • 插入 11 → 槽位 1(冲突),步长 h2(11) = 1 + (11 % 4) = 3,检查 1 + 3 = 4(冲突),再检查 4 + 3 = 2(成功)

最终哈希表:

槽位 0: []
槽位 1: [1]
槽位 2: [11]
槽位 3: []
槽位 4: [6]

3. 再哈希法

在发生冲突后,可以使用另一个哈希函数对该元素进行再哈希,找到一个新的槽位。

使用初始哈希函数 h1(k) = k % 5,当插入 10 时:

  • h1(10) = 0(槽位 0 已占用)
  • 使用新的哈希函数 h2(k) = (k / 5) % 5,计算:
    • h2(10) = 2(槽位 2 已占用)
  • 再次使用 h1 计算:
    • h1(10 + 1) = 1(槽位 1 已占用)
    • h1(10 + 2) = 3(放入槽位 3

最终哈希表如下:

槽位 0: [0]
槽位 1: [1]
槽位 2: [2]
槽位 3: [10]
槽位 4: [4]

4. 哈希桶扩容

如果哈希表的负载因子超过某个阈值,可以增加哈希表的大小,并重新计算所有元素的哈希值并重新分配到新的槽位。这有助于减少冲突并提高性能。

哈希表的负载因子是一个衡量哈希表填充程度的重要指标,通常用公式表示为:

负载因子 = 哈希表中的元素数量 / 哈希表的槽位总数

负载因子的意义:

  • 高负载因子:当负载因子接近或超过 1 时,表示哈希表的槽位几乎被填满,可能导致更多的哈希冲突,从而影响查找、插入和删除的性能。
  • 低负载因子:负载因子较低时,哈希表的空槽较多,冲突较少,性能较好,但会导致内存浪费。

负载因子的调整:

通常,当负载因子超过某个设定的阈值(例如 0.7 或 0.75),就会进行扩容。扩容时,哈希表的槽位数量增加,所有元素需要重新哈希并放入新的槽位中。

假设哈希表的大小为 5,当前负载因子超过 0.7,我们决定扩容到 10。在扩容时,所有元素的哈希值需要重新计算:

  • 原哈希表:
槽位 0: [0]
槽位 1: [1]
槽位 2: [2]
槽位 3: [3]
槽位 4: [4]
  • 扩容后,哈希函数改为 h(k) = k % 10,插入后的哈希表:
槽位 0: []
槽位 1: [1]
槽位 2: [2]
槽位 3: [3]
槽位 4: [4]
槽位 5: [5]
槽位 6: []
槽位 7: []
槽位 8: []
槽位 9: []

5.方法比较 

5.1. 链接法

优点:

  • 容易实现,简单明了。
  • 动态性好,可以存储任意数量的元素,只受限于内存。
  • 插入和删除操作较快,不需要重新哈希。

缺点:

  • 在某些情况下,链表可能会很长,导致查找性能下降。如果链表过长,可能导致性能接近于线性查找。
  • 需要额外的内存来存储链表节点。

5.2. 开放寻址法

优点:

  • 所有元素都存储在哈希表内部,节省了额外的内存。
  • 不需要额外的链表,查找时不需要遍历。

缺点:

  • 哈希表的负载因子需要控制在较低水平,通常小于 0.7,否则性能显著下降。
  • 在频繁冲突的情况下,查找效率会下降,且可能需要进行多次探测。
  • 删除操作复杂,可能导致“探测链”的问题,影响后续查找性能。

5.3. 再哈希法

优点:

  • 通过使用不同的哈希函数,能有效地减少冲突。
  • 可与其他方法结合使用,灵活性高。

缺点:

  • 需要额外的计算和存储开销,可能导致性能下降。
  • 在大量元素插入时,可能需要频繁地进行哈希计算。

5.4. 哈希桶扩容

优点:

  • 通过扩容可以有效降低负载因子,从而减少冲突。
  • 能够保持较高的性能,特别是在处理大量数据时。

缺点:

  • 扩容过程可能需要遍历整个哈希表,重新计算哈希值,导致短时间内性能下降。
  • 增加了内存的使用和管理复杂度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/882492.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

汉王手写签批控件如何在谷歌、火狐、Edge等浏览器使用

背景 近日,有网友咨询汉王手写签批控件是否可以通过allWebPlugin中间件技术加载到谷歌、火狐、Edge等浏览器?为此,笔者详细了解了一下汉王手写签批控件,它是一个标准的ActiveX控件,曾经主要在IE浏览器使用,…

【计算机基础】用bat命令将Unity导出PC包转成单个exe可执行文件

Unity打包成exe可执行文件 上边连接是很久以前用过的方法,发现操作有些不一样了,并且如果按上述操作比较麻烦,所以写了个bat命令。 图1、导出的pc程序 如图1是导出的pc程序,点击exe文件可运行该程序。 添加pack_project.bat文件 …

大数据Flink(一百二十二):阿里云Flink MySQL连接器介绍

文章目录 阿里云Flink MySQL连接器介绍 一、特色功能 二、​​​​​​​语法结构 三、​​​​​​​​​​​​​​WITH参数 阿里云Flink MySQL连接器介绍 阿里云提供了MySQL连接器,其作为源表时,扮演的就是flink cdc的角色。 一、特色功能 MySQ…

操作系统 | 学习笔记 | | 王道 | 5.3 磁盘和固态硬盘

5.3 磁盘和固态硬盘 5.3.1 磁盘 磁盘结构 磁盘:磁盘的表面由一些磁性物质组成,可以用这些磁性物质来记录二进制数据 磁道:磁盘的盘面被划分成一个个磁道。这样的一个“圈”就是一个磁道 扇区:一个磁道又被划分成一个个扇区&am…

大数据毕业设计选题推荐-网络电视剧收视率分析系统-Hive-Hadoop-Spark

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

通信工程学习:什么是NFVO网络功能虚拟化编排器

NFVO:网络功能虚拟化编排器 NFVO(Network Functions Virtualization Orchestrator),即网络功能虚拟化编排器,是网络功能虚拟化(NFV)架构中的核心组件之一。NFV是一种将传统电信网络中的网络节点…

从零开始学习Python

目录 从零开始学习Python 引言 环境搭建 安装Python解释器 选择IDE 基础语法 注释 变量和数据类型 变量命名规则 数据类型 运算符 算术运算符 比较运算符 逻辑运算符 输入和输出 控制流 条件语句 循环语句 for循环 while循环 循环控制语句 函数和模块 定…

黑马智数Day3

渲染基础Table列表 封装接口: export function getCardListAPI(params) {return request({url: /parking/card/list,params}) } 具体实现: import { getCardListAPI } from /apis/cardexport default {data() {return {// 请求参数params: {page: 1,pa…

乌克兰因安全风险首次禁用Telegram

据BleepingComputer消息,乌克兰国家网络安全协调中心 (NCCC) 以国家安全为由,已下令限制在政府机构、军事单位和关键基础设施内使用 Telegram 消息应用程序。 这一消息通过NCCC的官方 Facebook 账号对外发布,在公告中乌…

【小程序】uniapp自定义图标组件可动态更换svg颜色

组件描述 通过图标名称加载对应svg,size参数调整图标大小,color参数调整图标颜色 解决思路: 存svg获svg,对象方式正则替换svg的fill值,不改变源文件,通过base64直接加载缓存svg源文件,避免重…

上传富文本插入文件时报错:JSON parse error: Unexpected character解决办法

方式一(加密解密): 1.前端 (1)安装 crypto-js npm install crypto-js(2)util下创建asc.js asc.js import CryptoJS from crypto-js// 需要和后端一致 const KEY CryptoJS.enc.Utf8.parse(…

爬虫逆向学习(七):补环境动态生成某数四代后缀MmEwMD

声明:本篇文章内容是整理并分享在学习网上各位大佬的优秀知识后的实战与踩坑记录 前言 这篇文章主要是研究如何动态生成后缀参数MmEwMD的,它是在文章爬虫逆向学习(六):补环境过某数四代的基础上进行研究的,代码也是在它基础上增…

C++之初识STL(概念)

STL(标准模板库) STL广义分类为:容器,算法,迭代器 * **容器**和**算法**之间通过**迭代器**进行无缝连接 意义:C的**面向对象**和**泛型编程**思想,目的就是**复用性的提升** STL六大组件 1. 容…

论文阅读:Omni-Kernel Network for Image Restoration

论文地址:https://ojs.aaai.org/index.php/AAAI/article/view/27907 项目地址:https://github.com/c-yn/OKNet 发表时间:2024 图像恢复的目的是从一个退化的低质量的观测中重建一个高质量的图像。最近,Transformer模型由于其强大…

JavaScript 安装库npm报错

今天在编写JavaScript代码时,缺少了包express。 const express require(express); const app express();app.get(/, (req, res) > {res.send(Hello, world!); });app.listen(3000, () > {console.log(Server is running on port 3000); });npm install exp…

【Redis技能熟练掌握之十年内功】

Redis技能熟练掌握之十年内功 1.redis是什么?为什么要使用redis?2.redis一般应用于什么场景(四个场景)?3. Redis持久化机制是什么?各自的优缺点?一般咋么用?4. redis五个基础类型支持…

速通汇编(七)BX、SI、DI寄存器,BP寄存器,直接寻址和间接寻址

下文中出现的"idata",指的都是任意常量 一,基于BX、SI、DI等寄存器的寻址形式 在第五篇中曾介绍过DS寄存器的作用,简要复习一下->速通汇编(五)认识段地址与偏移地址,CS、IP寄存器和jmp指令&a…

百度飞浆Paddle OCR检测和识别【OCR数据收集、标注、数据集划分、检测识别模型训练、导出模型】

文章目录 前言一、OCR数据集采集二、OCR数据标注三、划分数据集四、数据训练五、导出模型 前言 1、我的电脑没有GPU,如果不使用AI Studio训练的话,第一遍我是按照CPU进行环境配置和训练的,可以参考这篇文章,我按着弄了一遍&#…

Kafka技术详解[1]:简介与基础概念

目录 1. Kafka入门 1.1 概述 1.1.1 初识Kafka 1.1.2 消息队列 1.1.3 生产者-消费者模式 1.1.4 消息中间件对比 1.1.5 ZooKeeper 1. Kafka入门 1.1 概述 1.1.1 初识Kafka Kafka是由Scala和Java语言开发的高吞吐量分布式消息发布和订阅系统,也是大数据技术领…

10月23-27日六西格玛绿带公开课即将在雄安新区开课

在金秋送爽、硕果累累的季节里,天行健管理咨询公司宣布了一项重要决定——定于10月23日至27日,在充满未来气息的河北雄安新区,举办一场旨在提升企业质量管理水平、培养精英人才的六西格玛绿带公开课。此次课程的举办,不仅是对当前…