hash冲突解决

1 开放寻址法

如冲突则根据指定步长向后寻找直到找到空位或没有位置

步长算法:

1.1 线性探查 步长为1 如threadlocal

key1:hash(key)+0

key2:hash(key)+1

key3:hash(key)+2

1.2 平方探测法  计算下一次的步长

key1:hash(key)+0

key2:hash(key)+1^2

key3:hash(key)+2^2

1.3  随机探测法 步长为随机生成的数  疑问:查询时如何查?如遍历查询有何意义?

缺点:

  • 查找性能不好:这种方法建立起来的哈希表,当冲突多的时候数据容易堆集在一起,这时候对查找不友好;
  • 删除节点不能真实删除浪费内存:删除结点的时候不能简单将结点的空间置空,否则将截断在它填入散列表之后的同义词结点查找路径。因此如果要删除结点,只能在被删结点上添加删除标记,而不能真正删除结点;
  • 如果哈希表的空间已经满了,还需要建立一个溢出表,来存入多出来的元素。
  • 为了减少冲突,负载因子要小些,导致内存浪费

 

2 再哈希

有多个不同的Hash函数,当发生冲突时,使用第二个,第三个,….,等哈希函数  直到不再冲突

也存在不能删除的问题? 如删除某元素后,查询另一个key调用第二个哈希函数后查询为null 无法确定继续处理还是key不存在?

缺点: 增加了计算时间

 

3 建立公共溢出区

将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表

缺点:  如未能命中哈希表 需要遍历查找溢出表 查询效率低

 

4 拉链法(或成树法, 树是一种特殊的链表。树形转化后 插入更慢(相比于头插法) 查询更快(冲突节点数目较多时))

如出现冲突,将其作为链表一个节点加入头或者尾巴处(分为头插法和尾插法)

拉链法的优点:

  • 处理冲突的方式简单,且无堆集现象,一般不会发生冲突,因此平均查找长度较短;
  • 由于拉链法中各链表上的结点空间是动态申请的,所以它更适合造表前无法确定表长的情况;
  • 删除结点操作易于实现,只要简单地删除链表上的相应的结点即可。

拉链法的缺点:需要额外的存储空间。

从HashMap的底层结构中我们可以看到,HashMap采用是数组+链表/红黑树的组合来作为底层结构,也就是开放地址法+链地址法的方式来实现HashMap。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值