哈希表是什么(键值对)
想象你有一个巨大的储物柜,每个抽屉都贴了标签。如果你要找“书包”,直接看标签“书包”对应的抽屉就行,不用一个一个翻。这就是哈希表的核心思想:通过键(Key)直接找到值(Value)。它存储的是键值对,比如 {"name": "小明"},其中 "name" 是键,“小明”是值。
哈希函数:把「找」变成「算」
哈希表之所以快,是因为它用了一个哈希函数。这个函数能把任意键(比如字符串“apple”)转换成一个数字(比如 3),然后直接去第 3 号位置找值。这样,查找就不再是“翻遍所有抽屉”,而是“算一下位置,直接拿”。
好的哈希函数应该计算快、结果均匀分布,避免很多键挤到同一个位置。
哈希冲突与拉链法
不同键可能算出相同位置,这叫哈希冲突。比如“apple”和“banana”都算出位置 3,怎么办?一种常见解法是拉链法:每个位置不再只放一个值,而是挂一个链表(或数组)。冲突的键值对都链在这个位置后面。查找时,先算位置,再在链表里顺序找。
为什么平均 O(1)、最坏 O(n)
| 情况 | 时间复杂度 | 原因 |
|---|---|---|
| 平均 | O(1) | 哈希函数均匀分布,每个位置链表很短,一步就能算到位置,再走几步链表。 |
| 最坏 | O(n) | 所有键都冲突到同一个位置,链表变得很长,退化成顺序查找。 |
所以哈希表性能依赖哈希函数质量和负载因子(元素个数/桶数)。
常见用途(去重/计数/查存在)
- 去重:用哈希集合记录已出现元素,遇到重复的就能快速跳过。
- 计数:用哈希表记录每个元素出现的次数,键是元素,值是次数。
- 查存在:比如检查用户名是否已被注册,用哈希表存所有已注册名,查询 O(1)。