【图解哈希表】从手写 Map 到哈希冲突解决策略!

0 阅读2分钟

🧠 引言

你知道吗?
JS 中的 Map、对象 {}、Python 的 dict、Java 的 HashMap 背后都藏着一个共同的“魔法结构”——哈希表(Hash Table)

今天我们不光要图解它的原理,还要手撸一个迷你版哈希表,并搞懂「哈希冲突」「链地址法」「开放地址法」这些“传说中”的概念。


🔍 一、什么是哈希表?

哈希表是一种通过哈希函数将“键”映射到“数组索引”的数据结构。

特点

操作时间复杂度
插入O(1)(理想)
查询O(1)(理想)
删除O(1)(理想)

🧠 二、图解哈希原理

key: "apple" → 哈希函数 → index: 2 → 存在数组[2]位置

📌 你只需要记住:
键(key) ➡ 哈希函数 ➡ 数组下标 ➡ 存值(value)


🧱 三、JS手写一个哈希表(链地址法)

✅ 1. 哈希函数(极简版)

function hash(key, size) {
  let hashCode = 0;
  for (let i = 0; i < key.length; i++) {
    hashCode += key.charCodeAt(i);
  }
  return hashCode % size;
}

✅ 2. 哈希表类实现(带冲突处理)

class HashTable {
  constructor(size = 7) {
    this.table = new Array(size);
  }

  set(key, value) {
    const index = hash(key, this.table.length);
    if (!this.table[index]) this.table[index] = [];
    for (let pair of this.table[index]) {
      if (pair[0] === key) {
        pair[1] = value;
        return;
      }
    }
    this.table[index].push([key, value]);
  }

  get(key) {
    const index = hash(key, this.table.length);
    const bucket = this.table[index];
    if (!bucket) return undefined;
    for (let pair of bucket) {
      if (pair[0] === key) return pair[1];
    }
    return undefined;
  }

  print() {
    console.log(this.table);
  }
}

✅ 3. 使用示例

const map = new HashTable();
map.set('apple', 100);
map.set('banana', 200);
map.set('grape', 300);
map.set('papple', 400); // 冲突概率提高
map.print();

console.log(map.get('banana')); // 输出 200

🧪 四、哈希冲突的两种解决方式

✅ 1. 链地址法(Chaining)

  • 数组或链表存冲突元素
  • 示例中 this.table[index] 是个数组

✅ 2. 开放地址法(Open Addressing)

  • 找下一个空位插入,常见策略:

    • 线性探测:+1、+2…
    • 二次探测:+1²、+2²…
    • 双重哈希

(此处暂不展开,后续有专文详解)


⚠️ 五、常见误区与易错点

错误行为正确做法
哈希函数写得太随意保证分布均匀 + 尽量减少冲突
没处理冲突最少需要链地址法 or 开放地址法
删除元素后未处理空洞在开放地址法中需要特殊处理
使用对象当键JS 中对象键默认会被转为字符串

🔄 六、JS 中的对象和 Map 区别?

对比点对象 {}Map
键类型只能是字符串或Symbol任意类型(包括对象)
顺序保证有插入顺序
迭代性能
内部结构哈希表哈希表 + 内部优化

🔧 七、拓展任务

  • 自己实现开放地址法哈希表(使用线性探测)
  • 编写一个「对象去重」工具(基于哈希)
  • 模拟 JS Map 支持任意对象键值存储

🧩 总结一句话

哈希表是现代语言背后的“黑科技”,也是面试题高频考点。掌握它,就等于掌握了高效存储与查找的核心武器!


下一篇预告:

📘 第5篇:【二叉树你还看不懂?】一文讲清二叉树的遍历、构造与应用!