【并发】第三篇 Hash冲突的解决方法

本文介绍了哈希冲突的概念及其在哈希表数据存储时引发的问题。接着详细讨论了解决哈希冲突的两种方法:开放地址法,包括线性探测再散列、二次探测再散列和伪随机探测再散列,以及再哈希法,通过两个不同的哈希函数来找到空闲位置。文中提供了简单的代码演示,并提到了Java中HashMap的链地址法实现。
摘要由CSDN通过智能技术生成


在这里插入图片描述

一. 简介

哈希(hash)是将任意长度的输入数据转化为固定长度的输出数据的算法。哈希函数会将输入数据压缩并映射为一个固定长度的哈希值,通常用一个字符串或数字来表示。

哈希冲突是指两个不同的输入值在经过哈希函数计算后得到了相同的哈希值。由于哈希函数的输出长度是固定的,而输入的数据可能有无限多的可能性,所以哈希冲突是不可避免的。

哈希冲突会引起一些问题,例如当使用哈希表进行数据存储时,如果有两个不同的键经过哈希函数计算得到了相同的哈希值,就会导致数据冲突,可能会导致数据丢失或覆盖。

二. 解决Hash冲突的方法

1. 开放地址法

当发生冲突时,继续寻找哈希表中的下一个空槽位,直到找到一个空槽位为止

1.1 线性探测再散列

当发生哈希冲突时,即两个不同的元素被哈希到了同一个槽位上,会依次向后探测下一个可用的槽位,直到找到一个空槽位或者遍历完整个哈希表。ThreadLocalMap 就是使用的线性探测再散列方法来解决Hash冲突的。
在这里插入图片描述

  • 具体步骤:
    根据哈希函数,将要插入的元素散列到哈希表的一个槽位
    如果该槽位已经被占用,就继续向下一个槽位探测,直到找到一个空槽位。
    如果遍历完整个哈希表仍然没有找到空槽位,就表示哈希表已满。
  • 缺点
    容易引起聚集,即当哈希表中有一部分槽位被占用时,会导致后续的插入操作耗时增加。此外,删除操作也会导致问题,因为删除一个元素后,后续的插入操作就无法正确地找到原本的位置了
  • 优点
    实现简单,易于理解和实现
  • 简单代码演示
public class LinearProbing {
   
    //初始容量
    private static final int TABLE_SIZE = 10;

    private static class HashEntry {
   
        private int key;
        private String value;

        public HashEntry(int key, String value) {
   
            this.key = key;
            this.value = value;
        }
    }

    public static class HashTable {
   
        private HashEntry[] table;

        public HashTable() {
   
            this.table = new HashEntry[TABLE_SIZE];
        }

        public void put(int key, String value) {
   
            int index = hash(key);
            while (table[index] != null && table[index].key != key) {
   
                index = (index + 1) % table.length;  //线性探测,依次向右查找
            }

            //可能存在hash冲突, 即hash值一样,但是key不一致
            if (table[index] != null) {
   
                //覆盖更新value操作
                table[index].value = value;
            } else {
   
                //通过线性探测,找一个空的槽位,直接插入
                table[index] = new HashEntry(key, value);
            }
        }

        public String get(int key) {
   
            int index = hash(key);
            //由于存在Hash冲突,那么有可能存在key通过hash运算后得出index是一致的,所以还需要比较key值是否一致
            while (table[index
  • 22
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖界的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值