hash表如何形成,hash函数如何计算,什么是hash冲突 如何解决 ,Golang map的底层原理及扩容机制

散列表

散列表(hash表):根据给定的关键字来计算出关键字在表中的地址的数据结构。也就是说,散列表建立了关键字和
存储地址之间的一种直接映射关系。

问题:如何建立映射管血

散列函数:一个把查找表中的关键字映射成该关键字对应的地址的函数,记为Hash(key)=Addr.

hash冲突

散列函数可能会把两个或两个以上的不同关键字映射到同一地址,称这种情况为“冲突
这些发生碰撞的不同关键字称为同义词。

image-20240730141829195

构造散列函数的条件:

  • 散列函数的定义域必须包含全部需要存储的关键字,而值域的范围则依赖于散列表的大小或地址范围。
  • 散列函数计算出来的地址应该能等概率、均匀地分布在整个地址空间,从而减少冲突的发生。
  • 散列函数应尽量简单,能够在较短的时间内就计算出任一关键字对应的散列地址。
1.常用的Hash函数的构造方法:
  • 直接定址法:直接取关键字的某个线性函数值为散列地址,散列函数为H(key)=axkey+b。式中,a和b是
    常数。这种方法计算最简单,并且不会产生冲突
  • 除留余数法:假定散列表表长为m,取一个不大于m但最接近或等于m的质数p,利用以下公式把关键字
    转换成散列地址。散列函数为H(kev)=key %p
    除留余数法的关键是选好p,使得每一个关键字通过该函数转换后等概率地映射到散列空间上的任一地址
    从而尽可能减少冲突的可能性
  • 数字分析法
    设关键字是r进制数(如十进制数),而r个数码在各位上出现的频率不一定相同,
    可能在某些位上分布均匀些
    每种数码出现的机会均等;而在某些位上分布不均匀,只有某几种数码经常出现,
    则应选取数码分布较为均匀
    的若干位作为散列地址。这种方法适合于已知的关键字集合

image-20240730142613377

手机号后四位分布比较均与 如果key为手机号那么取手机号后四位为散列值

4.平方取中法
顾名思义,取关键字的平方值的中间几位作为散列地址。具体取多少位要看实际情况而定。这种方法得
到的散列地址与关键字的每一位都有关系,使得散列地址分布比较均匀。

Eg

12342=1522756 取中间三位227作为散列地址

23452=5499025 取中间三位990作为散列地址

5.折叠法

将关键字分割成位数相同的几部分 (最后一部分的位数可以短一些),然后取这几部分的叠加和作为
散列地址,这种方法称为折叠法。关键字位数很多,而且关键字中每一位上数字分布大致均匀时,可
以采用折香法得到散列地址。
Eg:关键字为1234567890散列表表长为3位可以将关键字分为四组每组3位
123456|7890然后这四组叠加求和123+456+789+0=1368 然后取后3位就能得到散列地址为368

2.常用的Hash函数的冲突处理办法
1.开放定址法

​ :将产生冲突的Hash地址作为自变量,通过某种冲突解决函数得到一个新的空闲的Hash地址。

		1)   线性探测法: 冲突发生时,顺序查看表中下一个单元 (当探测到表尾地址m-1时,探测地址是表首地址0),直到找出一个空闲单元 (当表未填满时一定能找到一个空闲单元)或查遍全表。

image-20240730154952929

如上图,11 、19、27经过运算后的映射下标都是3,由于3被最开始的11占用,那19就不得不后移占住后面空着的下表,这样就会产生连锁反应导致原来hash值是4的key也要后移,这样查找起来就非常麻烦

比如我找27,先计算得出27的hash值是3,但发下3下面存的11,只能往后找4 – 19不是,继续遍历到5 – 17 找到了

2)平方探测法:设发生冲突的地址为d,平方探测法得到的新的地址序列为d+12,d-12,d+22,d-22
平方探测法是一种较好的处理冲突的方法,可以避免出现“堆积”问题,它的缺点是不能探测到散列
表上的所有单元,但至少能探测到一半单元。

image-20240730155513651

3)再散列法:又称为双散列法。需要使用两个散列函数,当通过第一个散列函数H(Key)得到的地址发
生冲突时,则利用第二个散列函数Hash2(Kev)计算该关键字的地址增量。

image-20240730155651274

4)伪随机序列法:当发生地址冲突时,地址增量为伪随机数序列,称为伪随机序列法。

2.拉链法:

对于不同的关键字可能会通过散列函数映射到同一地址,为了避免非同义词
发生冲突,可以把所有的同义词存储在一个线性链表中,这个线性链表由其散列地址唯
标识。拉链法适用于经常进行插入和删除的情况

3.散列表的查找过程

类似于构造散列表,给定一个关键字Key。
先根据散列函数计算出其散列地址。然后检查散列地址位置有没有关键字.
1)如果没有,表明该关键字不存在,返回查找失败。
2)如果有,则检查该记录是否等于关键字。

  • 如果等于关键字,返回查找成功。
  • 如果不等于,则按照给定的冲突处理办法来计算下一个散列地址,再用该地址去执行上述过程。
4.散列表的查找性能

性能和装填因子有关

什么是装填因子?

image-20240730160416593

image-20240730160759116

Golang中map的hash值是如何计算如何存的?

在日常编程中,map的底层也是hash表,但map 的 key 键不仅仅是数字,还可能是字符串。由于我们之前讨论的哈希函数主要是针对数字进行计算的,因此,当 key 为字符串时,首先需要将字符串转化为整数,然后再经过哈希函数的运算产生哈希值。

在 Go 中,map 的哈希值会通过取模运算(或其他方式)转换成哈希表中的一个具体位置,这个位置称为映射地址。映射地址通常对应于一个桶,桶是一个存储多个键值对的容器。每个桶可以存储多个键值对,以处理哈希冲突。桶的数量通常与哈希表的容量有关。

溢出桶:如果主桶已满,则会创建一个溢出桶,将多余的键值对存储在溢出桶中。如果溢出桶也满了,就会继续创建新的溢出桶,形成一个链表结构。

image-20240730161624131

ps:个人认为桶和线性链表及其相似

go map的扩容机制

扩容的时机装载因⼦超过⼀定的阈值或者使⽤了太多的溢出桶时。

扩容的规则:
  1. 等量扩容 使⽤溢出桶太多的时候会进⾏等量扩容。申请和原来等量的内容,将原来的数据重新整理

后,写⼊到新的内存中。可以简单的认为是⼀次内存整理,⽬的是提⾼查询效率。

  1. 增量扩容 分成两步: 第⼀步进⼊扩容状态,先申请⼀块新的内存,翻倍增加桶的数量,此时

buckets指向新分配的桶,oldbuckets指向原来的桶。 第⼆步,重新计算⽼的桶中的哈希值在新

的桶内的位置(取模或者位操作),将旧数据⽤渐进式的⽅式拷⻉到新的桶中。

渐进式迁移分两块,⼀⽅⾯会从第⼀个桶开始,顺序迁移每⼀个桶,如果下⼀个桶已经迁移,则跳

过。另⼀⽅⾯,当我们操作某⼀个桶的元素时,会迁移两个桶,进⽽保证经过⼀些操作后⼀定能够完

成迁移。

访问迁移的map时会放生什么?

当我们访问⼀个正在迁移的Map时,如果存在oldbuckets,那么直接去中oldbuckets寻找数据。当

我们遍历⼀个正在迁移的Map时,新的和旧的就会遍历,如果⼀个旧的的桶已经迁移⾛了,那么就直

接跳过,反正不在旧的就在新的⾥。Map遍历本⾝就是⽆序的。

定能够完

成迁移。

访问迁移的map时会放生什么?

当我们访问⼀个正在迁移的Map时,如果存在oldbuckets,那么直接去中oldbuckets寻找数据。当

我们遍历⼀个正在迁移的Map时,新的和旧的就会遍历,如果⼀个旧的的桶已经迁移⾛了,那么就直

接跳过,反正不在旧的就在新的⾥。Map遍历本⾝就是⽆序的。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

装饰大师——装饰模式(Java实现)

引言 大家好,上期我们介绍了装饰模式在Python中的实现,今天,我们将继续探讨装饰模式,并展示如何在Java中实现它。 装饰模式概述 装饰模式的核心思想是将功能附加到对象上,而不是通过继承来实现,这种模式…

蓄势赋能 数智化转型掌舵人百望云杨正道荣膺“先锋人物”

2024年,在数据与智能的双涡轮驱动下,我们迎来了一个以智能科技为核心的新质生产力大爆发时代。在数智化浪潮的推动下,全球企业正站在转型升级的十字路口。在这个充满变革的时代,企业转型升级的道路充满挑战,但也孕育着…

每日一题系列-两个数组的交集

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” class Solution { public:int hash[1010] {0};vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {vector<int> ret;for(a…

WPF用户登录界面设计-使用SQLite数据库进行存储

一、SQLite数据库介绍 SQLite是一款轻量级的关系型数据库&#xff0c;它小巧高效&#xff0c;无需服务器配置&#xff0c;仅需单一文件即可存储数据。SQLite跨平台支持&#xff0c;易于集成到各种应用程序中&#xff0c;并支持SQL语言进行数据操作。它保证了数据的完整性、一致…

计算机网络03

文章目录 重传机制超时重传快速重传SACK 方法Duplicate SACK 滑动窗口流量控制操作系统缓冲区与滑动窗口的关系窗口关闭糊涂窗口综合症 拥塞控制慢启动拥塞避免算法拥塞发生快速恢复 如何理解是 TCP 面向字节流协议&#xff1f;如何理解字节流&#xff1f;如何解决粘包&#xf…

免费【2024】springboot 滁州市特产销售系统

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

vue2学习 -- 核心语法

文章目录 前置简介1. 模板语法2. 数据2.1 数据绑定2.2 el与data的两种写法2.3 MVVM模型2.4 Object.defineProperty2.5 Vue中的数据代理 3. 事件3.1 事件处理3.2 事件修饰符3.3 键盘事件 4. 计算属性5. 监视(侦听)属性5.1 书写形式5.2 深度监视5.3 简写形式5.4 计算属性和监听属…

大数据-53 Kafka 基本架构核心概念 Producer Consumer Broker Topic Partition Offset 基础概念了解

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

美团2024年春招第一场笔试[测开方向],编程题+选择题详解,ACM式C++解法

编程题&选择题 编程题小美的平衡矩阵思路代码 小美的数组询问思路代码 验证工号思路代码 选择题1.在计算机网络中&#xff0c;端口号的作用是什么2.HTTPS协议通过使用哪些机制来确保通信的安全性3.Etag用于标识资源的唯一标识符&#xff0c;他可以用于4.在一个单道系统中&a…

Nacos配置到springboot快速入门(笔记)

本人学习中的简单笔记&#xff0c;本文写的极其不详细&#xff0c;慎看&#xff01;&#xff01;&#xff01; Nacos 简介 Nacos 致力于帮助开发者发现、配置和管理微服务。它提供了一组简单易用的特性集&#xff0c;帮助开发者快速实现动态服务发现、服务配置、服务元数据及…

CSCP、CPIM和CLMP三大证书的区别?如何选择?

在制造型企业、供应链和运营管理专业人士都会不断寻找方法来提升他们的技能和职业前景。三种流行的认证——CSCP&#xff08;Certified Supply Chain Professional&#xff09;、CPIM&#xff08;Certified in Planning and Inventory Management&#xff09;以及CLMP&#xff…

创客项目秀 | 基于xiao的光剑

在《星球大战》宇宙中&#xff0c;光剑不仅仅是武器;它们是持有者与原力的桥梁&#xff0c;制造一把光剑几乎是每个创客的梦想&#xff0c;今天给大家带来的是国外大学生团队制作的可伸缩光剑项目。 材料清单&#xff1a; 电机驱动模块1:90减速电机套装MP3模块、喇叭Xiao RP2…

一「骑」就LUCKY!凯迪拉氪强劲动力,带你一路顺畅,幸运随行!

好运&#xff0c;其实就是毫不费劲的完成心里所想的事情。简单来说&#xff0c;是不需要太多努力&#xff0c;就能得到比较大的回报。每个人都希望自己拥有好运气&#xff0c;但这就跟抽盲盒一样&#xff0c;可能穷极一生都享受不到。 所以&#xff0c;与其期待虚无缥缈的好运…

爬虫问题---ChromeDriver的安装和使用

一、安装 1.查看chrome的版本 在浏览器里面输入 chrome://version/ 回车查看浏览器版本 Chrome的版本要和ChromeDriver的版本对应&#xff0c;否则会出现版本问题。 2.ChromeDriver的版本选择 114之前的版本&#xff1a;https://chromedriver.storage.googleapis.com/index.ht…

生成式AI在金融领域的研究与应用

引言 科技的进步日新月异&#xff0c;伴随着移动终端与网络的不断迭代&#xff0c;人工智能领域也从专家系统到卷积神经网络&#xff0c;从Transform到生成式AI&#xff0c;乃至未来的AGI&#xff0c;不断改变我们的生活方式&#xff0c; 科技发展驱动人类社会加速迈向全面智能…

无人机之交通管理篇

无人机技术已经渗透到社会的各个领域&#xff0c;其中交通监控与管理便是其应用的重要方向之一。无人机凭借其独特的优势&#xff0c;如高效性、灵活性、实时性等&#xff0c;为交通监控与管理带来了革命性的变革。 一、无人机在交通监控中的应用 1、实时监控与数据采集 无人…

SuperMap iDesktopXiClient3D for WebGL 基于确定性空间插值生成水体流场

目录 摘要1 原始数据解析2 数据空间插值2.1流场UVW0.dat文件转xlsx2.2生成流场点数据2.3生成U、V栅格数据2.4裁剪U、V栅格数据2.5生成零值棋盘网格2.6生成U、V棋盘栅格 3 棋盘栅格转棋盘点3.1U、V棋盘栅格矢量化3.2U、V字段追加3.3流场数据JSON标准解析3.3.1流场数据JSON范例3.…

数据结构与算法-索引堆及其优化

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、索引堆…

基于SpringBoot+Vue的档案管理系统(带1w+文档)

基于SpringBootVue的档案管理系统(带1w文档) 基于SpringBootVue的档案管理系统(带1w文档) 随着信息化的不断发展&#xff0c;科技的进步也越来越大。软件编程是一个不断发展的行业&#xff0c;每个行业都必须进行适合自身特点的系统开发&#xff0c;才能在机构中生存和发展。当…

区块链技术在智能城市中的创新应用探索

随着全球城市化进程的加速和信息技术的快速发展&#xff0c;智能城市成为了未来城市发展的重要方向。在智能城市建设中&#xff0c;区块链技术作为一种去中心化、安全和透明的分布式账本技术&#xff0c;正逐渐展现出其在优化城市管理、提升公共服务和增强城市安全性方面的潜力…