解决哈希冲突的几种方法

什么是hash冲突

哈希函数是一个映像,把任意长度的输入,通过Hash算法变换成固定长度的输出,这个输出就是Hash值; 当两个不同的输入,产生了同一个输出值即为哈希冲突

解决方式

开放定址法

开放寻址法的核心思想是,如果出现了散列冲突,我们就重新探测一一个空闲位置,将其插入。比如,我们可以使用线性探测法。当我们往散列表中插入数据时,如果某个数据经过散列函数散列之后,存储位置已经被占用了,我们就从当前位置开始,依次往后查找,看是否有空闲位置,如果遍历到尾部都没有找到空闲的位置,那么我们就再从表头开始找,直到找到为止

①. 线性探测 :按顺序决定哈希值时,如果某数据的哈希值已经存在,则在原来哈希值的基础上往后加一个单位,直至不发生哈希冲突。

②. 再平方探测 :按顺序决定哈希值时,如果某数据的哈希值已经存在,则在原来哈希值的基础上先加1的平方个单位,若仍然存在则减1的平方个单位。随之是2的平方,3的平方等等。直至不发生哈希冲突。

③. 伪随机探测 :按顺序决定哈希值时,如果某数据已经存在,通过随机函数随机生成一个数,在原来哈希值的基础上加上随机数,直至不发生哈希冲突。

链地址法(拉链法)

链地址法(Separate Chaining)的思路是将哈希值相同的元素构成一个同义词的单向链表,并将单向链表的头指针存放在哈希表的第 i 个单元中,查找、插入和删除主要在同义词链表中进行

如下一组数字:(32、40、36、53、16、46、71、27、42、24、49、64),哈希表长度为13,哈希函数为 H(key)=key%13,则链表法结果如下:

0       
1  -> 40 -> 27 -> 53 
2
3  -> 16 -> 42
4
5
6  -> 32 -> 71
7  -> 46
8
9
10 -> 36 -> 49
11 -> 24
12 -> 64

下面看一张动态图可能会更清晰(图片均来源于网络):

注意: 链地址法是主流开发语言中 HashMap 冲突的解决办法,如 Java、Go 等。以 Java 为例,JDK1.7 完全采用单链表来存储同义词,JDK 1.8 则采用了一种混合模式,对于链表长度大于 8 的,会转换为红黑树存储。

优点:处理简单,容易删除,只需要简单地删去链表上相应的结点即可;

缺点:一旦哈希冲突多了,哈希表会退化成链表,查询效率会从O(1)变为O(n)。JDK8的HashMap针对这种情况有做优化,冲突超过8个会将链表转换为红黑树,提高查询效率。

再哈希法

对于冲突的哈希值再次进行哈希处理,直至没有哈希冲突。

采用哈希函数,而不是一个; 如果第一个哈希函数计算的哈希码发生冲突了,就采用第二个哈希函数重新计算哈希码,直到不冲突为止; 查询时也是一样,依次调用不同的哈希函数计算哈希码,直到Key相等。

int hash = hash1(key)、hash2(key)、hash3(key)......

缺点:这种方式会增加哈希计算的开销,影响读写的效率。

建立公共溢出区

在创建哈希表的同时,再额外创建一个公共溢出区,专门用来存放发生哈希冲突的元素。查找时,先从哈希表查,查不到再去公共溢出区查。

缺点:哈希冲突多了,公共溢出区会膨胀的非常厉害,查询的效率也有影响。

最后总结

  1. 拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;

  2. 由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;

  3. 开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时, 拉链法中增加的指针域可忽略不计,因此节省空间;

  4. 在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表, 删除结点不能简单地将被删结点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。

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

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

相关文章

PyQt5多线程使用

PyQt5多线程使用 本案例使用PyQt5多线程实现一个UI界面同时显示3个时间实时更新控件,从而直观地了解到Qt多线程是如何进行工作的。 from PyQt5.QtCore import QThread,pyqtSignal,QDateTime from PyQt5.QtWidgets import QApplication,QDialog,QLineEdit,QVBoxLay…

[Android]实现一个权限申请类

[Android]实现一个权限申请类 导言 在引入了动态权限申请之后,Android的权限申请就变得尤为繁琐,若是按照原有的方法一板一眼地进行申请,样板代码未免太多。因此本篇文章就使用ActivityResult API,来实现一个简单的权限申请类来帮…

【漏洞复现】Kubernetes PPROF内存泄漏漏洞(CVE-2019-11248)

Nx01 产品简介 Kubernetes(简称K8S)是Google在2014年开源的一个容器集群管理系统。它用于容器化应用程序的部署、扩展和管理,目标是让部署容器化应用简单且高效。 Nx02 漏洞描述 漏洞存在于Kubernetes的1.18.6版本之前,可能导致未…

「解析」Jetson配置 git服务

这两天感冒了在家休养,想着把之前买的 Jetson 开发板用起来,买Jetson的初衷就是用来学习Linux系统,顺道可以部署算法,以及一些其他需求,相比树莓派而言,Jetson开发相对更贵,但是其配备了英伟达的…

conda 安装, 配置以及使用

文章目录 1. 安装2. 配置2.1 如何配置2.2 快速设置取消自动进入 base 环境conda 添加清华源pip 添加清华源pip 更新为最新版本 3. 使用 conda 是 python 的环境管理工具包,非常好用,特别是 miniconda 相对于 conda 不需要安装其他的工具,而且…

详细讲解Python中的aioschedule定时任务操作

目录 前言1. 基本概念2. 基本API3. Demo 前言 如果下面的函数库无法执行,出现类似:(前提是python3.7以上) AttributeError: module ‘asyncio‘ has no attribute ‘run‘请检查run是否可跳转,如果无法跳转&#xff…

Jenkins实现基础CI操作配合python

条件: gitlab准备好 jenkins准备好 (不会java项目, 故跳过Maven打jar包) jenkins配置 在配置里通过插件Git Parameter配置Git,以便于从gitlab 拉去代码到Jenkins r容器内 /var/jenkins_home/ 刚接触python 项目好像不需要构建,直接推送到远…

深度学习弱光图像增强入门学习贴及相关可参考工作推荐

0 引言 先表明身份,在过去三年的时间里,发表弱光图像增强的SCI工作多篇,后续会在Github的代码库构建好之后,分享代码链接,欢迎关注(由于工作过于垃圾,因此咱还是以大佬的工作作为参考 首先&am…

推荐一款低成本半桥驱动器集成电路 SIC631CD-T1-GE3

SIC631CD-T1-GE3 是经过优化的集成功率级解决方案用于同步降压应用,提供大电流、高电压效率高,功率密度高。使电压调节器设计能够提供高达50 A的电流每相持续电流。内部功率MOSFET利用Vishay的最先进的第四代TrenchFET技术行业基准绩效将显著降低开关和传…

深入浅出Spring AOP

第1章:引言 大家好,我是小黑,咱们今天要聊的是Java中Spring框架的AOP(面向切面编程)。对于程序员来说,理解AOP对于掌握Spring框架来说是超级关键的。它像是魔法一样,能让咱们在不改变原有代码的…

XSS漏洞:prompt.mi靶场通关

xss系列往期文章: 初识XSS漏洞-CSDN博客 利用XSS漏洞打cookie-CSDN博客 XSS漏洞:xss-labs靶场通关-CSDN博客 目录 第0关 第1关 第2关 第3关 第4关 第5关 第6关 第7关 第8关 第9关 第A关 第B关 第C关 第D关 第E关 第F关 上一篇文章给…

c语言将csv文件中的XY轴数据转换为html波形图

目标: c语言实现一个最简化的csv转html波形图显示方案。 csv文件格式: 共两行数据,第一行是x轴数据,第二行是y轴数据。 csv文件名分为3段: 波形图名称,x轴名称,y轴名称。 c代码: int csv2html…

springboot集成shiro+前端vue,前后端分离项目遇到跨域以及sessionid拿不到等问题

近期在写前后端分离的项目,由于前后端分离导致原来使用的shiro配置无法满足现有系统要求。同时在前后端分离项目中存在的一些问题。例如,一些用户信息需要存储在后端方便进行安全性判断,但这些存储在后端的session前端却获取不到(…

开发知识点-java基础

java基础知识整理 windows 多版本java jar包不能直接打开 需要java -jar问题解决 windows 多版本 控制面板 java15 download 多版本 https://www.cnblogs.com/chenmingjun/p/9941191.html https://gitee.com/shixinke/JC-jEnv/repository/archive/master.zip java jar包不…

2024年AMC8历年真题练一练和答案详解(10),以及全真模拟题

六分成长继续为您分享AMC8历年真题,最后两天通过高质量的真题来体会快速思考、做对题目的策略。 题目从575道在线题库(来自于往年真题)中抽取5道题,每道题目均会标记出自年份和当年度的序号,并附上详细解析。【使用六…

CUDA tips

命令行查看核函数消耗的寄存器和共享内存数量 nvcc --ptxas-options-v reduce_sum.cu nvprof 使用 由于 8.0 及以上计算能力的显卡用不了 nvprof,官方建议用 nsight system 和 ncu,但是如果只想命令行打印表格查看 kernel 概况感觉还是 nvprof 方便&am…

三个方法解决pycharm中 ,alt +enter自动导入包的快捷键失效的问题

目录 1. 检查IDE设置:查看IDE的设置,确保自动导入包的功能是启用的 2. file>settings>keymap 里没有找到 alt enter 的快捷键 3. 按照网上教程说的如下选项勾上,也没用 4. 在右侧的General设置界面中,找到并点击Auto I…

YOLOv5改进 | 2023主干篇 | 多种轻量化卷积优化PP-HGNetV2改进主干(全网独家创新)

一、本文介绍 Hello,大家好,上一篇博客我们讲了利用HGNetV2去替换YOLOv5的主干,经过结构的研究我们可以发现在HGNetV2的网络中有大量的卷积存在,所以我们可以用一种更加轻量化的卷积去优化HGNetV2从而达到更加轻量化的效果(亲测优化后的HGNetV2网络比正常HGNetV2精度更高…

Mac OS系统 SVN客户端 smartSVN 安装和基础使用

一、下载SVN客户端 官网地址,可以根据自己的系统下载 https://www.smartsvn.com/download/ 二、安装客户端和激活 第一步安装,很简单。 第二步,激活,选择激活文件 创建一个许可文件,例如 smartSvn.license。 内容如…

RabbitMQ交换机(1)

1.交换机Exchange RabbitMQ消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上,通常生产者甚至都不知道这些消息传递传递到了哪些队列中。 相反,生产者只能将消息发送到交换机(exchange),交换机工作的内容非常简单&am…