map使用注意事项及底层原理

本文探讨了Golang中map的数据结构特性,如何避免哈希碰撞,以及拉链法和开放地址法的冲突解决方案。重点介绍了哈希函数的重要性、哈希表的工作原理,并分析了评价hash算法的标准。同时揭示了map中元素不可寻址的原因和map在实际应用中的选择策略。
摘要由CSDN通过智能技术生成

map

  • map 为一个hash table的引用
  • 不能对map中的值取地址
  • map的index需要可比较,如果想用无法比较的值作为key,可以把key序列化为字符串
  • map可以在迭代的过程中删除元素,迭代器不会失效
  • golang中没有set,可以用map实现set功能,用key存放 set中的值,val中存放bool类型形如map[int]bool

for range 遍历map使用注意点
链接

hash函数

哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。

哈希函数的特点

  • 相同的输入一定得到相同的输出;
    哈希函数内部映射规则不变,y=f(x),x相同,y也相同
  • 不同的输入大概率得到不同的输出
    输出hash值为一个有界值,当输入无限时,输出必然会产生相同。输入不同,但hash值相同的现象也叫做hash碰撞。hash碰撞不可避免,我们只能从工程上解决hash碰撞的问题

哈希表

hash表定义

hash表也叫散列表。是根据键(Key)而直接访问在内存储存位置的数据结构。也就是说,我们存储数据时需要提供key和val,通过hash算法对key求hash值,然后映射到数组上(一般规则为hash_val %array_len = array_index)

hash碰撞的解决方法

冲突解决方法图片以及内容来源 如有版权问题,请联系我删除

开放地址法

基本思想:当我们向当前哈希表写入新的数据时,如果发生了冲突,就会将键值对写入到下一个索引不为空的位

[图非原创]

图片分析
如图可见hash表中存放的为pair对{key,value}。

存入{key1,value}时 :

  1. 求出数组下标 : array_index= hash(key)%array_len
  2. 赋值: array[array_index] = {key1,value}

存入{key2,value}时,
假设: hash(key2) != hash(key1) && hash(key) % array_len == hash(key) % array_len
此时根据key2求出的array_index,与key1求出的array_index相同,插入数据时我们需要认为判断pair对{key,value}是否为同一个,如果不是则向后找到第一个索引不为空(非越界)的位置插入

存入{key3,value}时,
假设: hash(key3) == hash(key1)
和插入{key2,value}相同

拉链法

基本思想: 实现拉链法一般会使用数组加上链表,不过一些编程语言会在拉链法的哈希中引入红黑树以优化性能,拉链法会使用链表数组作为哈希底层的数据结构,我们可以将它看成可以扩展的二维数组

[图非原创]

两种方式实现hash表比较

在实现相同规模存储的情况下,开放地址法需要的空间大于拉链法(数组内存)
数组大小一样,且存储数据小于数组容量,且不发生碰撞时,由于拉链法需要动态分配内存,创建变量位于堆上,读写速率慢于开放地址法。
实际应用中,更多会选择拉链法实现hash表

map中元素不可寻址的原因

装载因子 = 元素数量 / 数组长度
装载因子越大,hash表读写性能越差
当装载因子过大时,golang map会重新分配内存空间,旧地址会失效,所以golang中map禁止了map元素的寻址

评价hash算法

由hash表实现我们可以知道,hash碰撞增加了hash表的时间复杂度。碰撞概率小就成了hash算法优劣评价的一个指标。如何让碰撞概率小?让hash结果更加均匀
所以hash值分布越均匀,则该hash算法越好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值