什么是哈希冲突?哈希冲突怎么解决?

一、哈希表

哈希表是一种以键对应值(key-indexed) 来存储数据的结构,只要输入要查找的键即key,即可查找到对应的值。
将键作为索引,这样就可以快速访问任意键的值。

1.1 哈希函数

哈希函数指将哈希表中元素的关键键值映射为元素存储位置的函数。
哈希表中元素是由哈希函数确定的。将数据元素的关键字K作为自变量,通过一定的函数关系(称为哈希函数),计算出的值,即为该元素的存储地址。
一个合适的哈希函数,需要具备一下两点

  1. 均匀性 k的值均匀分布在哈希表中;
  2. 简单 以提高地址计算的速度;

1.2 哈希冲突

不同的值,由哈希函数计算出的哈希值可能相同

在这里插入图片描述
假设我们将需要存的数n,存的索引值 = n % 10
现在需要将20存入该表中,计算出的键值为0,但是该位置已经有数据了,即发生了哈希冲突.

1.3解决哈希冲突

1.3.1 开放地址法

开放定址法就是一旦发生了冲突,就去寻找下一个空的哈希地址,只要哈希表足够大,空的哈希地址总能找到,然后将数据存入该位置.

1.3.2 链地址法(重点)

将每个哈希表的节点当做一个链表的头部或者树的根节点又或者其他的数据结构.
例如,将哈希表的节点当做一个链表的头.将20存入之间的那个哈希表.
在这里插入图片描述

### 哈希冲突的概念 哈希函数的作用是将任意长度的数据映射到固定大小的空间中。由于目标空间有限而输入数据无限多样,因此不可避免地会出现多个不同输入被映射至相同输出的情况,这种情况即被称为哈希冲突或者哈希碰撞[^2]。 ### 发生机制 当两个或更多不同的键通过同一个哈希函数计算得到相同的索引值时就会引发哈希冲突。这是因为哈希表中的存储容量总是有限的,而实际应用中可能出现的键值组合几乎是无穷无尽的,所以即使设计再优秀的哈希算法也无法彻底杜绝这种现象的发生[^3]。 ### 碰撞处理方式 为了应对哈希冲突问题,存在多种解决方案: #### 开放定址法(Open Addressing) 这种方法又称为闭散列,在检测到冲突之后会在原位置附近继续寻找新的可用槽位放置元素。线性探测是一种简单的实现形式,它按照固定的增量顺序依次检查后续的位置直到找到空闲单元为止;另一种变体二次探测则采用平方级数作为步长来避免聚集效应[^4]。 ```python def linear_probing(hash_table, hash_value, size): i = 0 while True: new_index = (hash_value + i) % size if not hash_table[new_index]: return new_index i += 1 ``` #### 链地址法(Separate Chaining) 链地址法则是在每一个桶里维护一个列表结构用于容纳所有具有相同哈希码的对象实例。每当有新成员加入却遭遇已有项占用同一入口的情形下,则直接追加到对应链接末端即可[^5]。 ```python class LinkedListNode: def __init__(self, key=None, value=None, next_node=None): self.key = key self.value = value self.next = next_node class HashTableWithChaining(dict): def put(self, key, value): index = hash(key) % len(self) node = self[index] if not node or node.key != key: self[index] = LinkedListNode(key=key, value=value, next_node=node) elif node and node.key == key: node.value = value else: current = node while current.next is not None: if current.key == key: break current = current.next if current.key == key: current.value = value else: current.next = LinkedListNode(key=key, value=value) ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值