Skip to content

哈希表

哈希表是实现 O(1) 查找的核心数据结构。

🗃️哈希表

哈希表 (大小: 7)
元素: 0 | 负载因子: 0.00
[0]
[1]
[2]
[3]
[4]
[5]
[6]
📊 时间复杂度
平均: O(1)
最坏: O(n) (所有元素冲突)
💡 链地址法
冲突元素存入链表,空间换时间,适合高负载

将任意键映射到固定范围的索引:

function hash(key, tableSize) {
let sum = 0;
for (const char of key) {
sum += char.charCodeAt(0);
}
return sum % tableSize; // 取模得到索引
}

好的哈希函数特征

  • 确定性:相同输入 → 相同输出
  • 均匀分布:减少冲突
  • 高效计算:O(1) 时间

当两个不同的键映射到同一索引时,需要处理冲突:

方法原理优点缺点
链地址法同一桶存链表简单、适合高负载需要额外空间
开放寻址向后探测空位缓存友好删除复杂、聚集问题

操作平均最坏说明
查找O(1)O(n)最坏:所有键冲突
插入O(1)O(n)可能需要扩容
删除O(1)O(n)开放寻址需标记删除
α=nm\alpha = \frac{n}{m}
  • n = 元素数量
  • m = 桶数量
  • α > 0.7 时建议扩容

// JavaScript 的 Map/Object 就是哈希表
const map = new Map();
map.set('name', 'Alice'); // O(1)
map.get('name'); // O(1)
map.has('name'); // O(1)
map.delete('name'); // O(1)
// Python 的 dict
user = {'name': 'Alice', 'age': 25}
user['name'] # O(1)
// Java 的 HashMap
Map<String, Integer> map = new HashMap<>();

  1. 键必须可哈希:不可变类型 (字符串、数字)
  2. 负载因子控制:过高影响性能
  3. 哈希函数选择:影响冲突率
  4. 不保证顺序:需要顺序用 LinkedHashMap