JavaScript中的哈希表

204 阅读2分钟

一、哈希表的基本概念

哈希表,又称散列表,是一种基于数组的数据结构。哈希表是一种通过哈希函数将键映射到值的数据结构。它的核心思想是将数据存储在一个数组中,通过计算键的哈希值来确定数据在数组中的位置。哈希表的主要优点是能够在平均情况下实现常数时间复杂度的查找、插入和删除操作。

1.1 哈希函数

哈希函数是哈希表的核心,它将输入的键转换为数组的索引。一个好的哈希函数应具备以下特性:

  • 确定性:相同的输入总是产生相同的输出。
  • 均匀性:不同的输入应尽可能均匀地分布到数组中,以减少冲突。
  • 快速计算:哈希函数的计算应尽可能快速,以提高性能。

1.2 冲突处理

由于哈希函数的输出范围有限,不同的键可能会映射到相同的索引,这种情况称为冲突。常见的冲突处理方法有:

  • 链式地址法:在每个数组索引处维护一个链表,所有映射到同一索引的元素都存储在该链表中。
  • 开放地址法:在数组中寻找下一个空位来存储冲突的元素。

二、JavaScript中的哈希表实现

例子中使用了链式地址法解决了哈希冲突问题,哈希表的实现主要是上面提到的哈希函数以及冲突处理

class HashTable {
    constructor(size) {
        this.size = size; // 哈希表大小
        this.table = new Array(size); // 初始化一个数组作为桶
    }

    // 哈希函数
    hash(key) {
        let hashValue = 0;
        for (let i = 0; i < key.length; i++) {
            hashValue = (hashValue + key.charCodeAt(i)) % this.size;
        }
        return hashValue;
    }

    // 插入键值对
    set(key, value) {
        let index = this.hash(key);

        if (!this.table[index]) {
            this.table[index] = []; // 如果桶为空,初始化为一个空数组
        }

        // 处理冲突:如果链表中已有相同的键,更新值
        for (let i = 0; i < this.table[index].length; i++) {
            if (this.table[index][i][0] === key) {
                this.table[index][i][1] = value;
                return;
            }
        }

        // 插入新的键值对
        this.table[index].push([key, value]);
    }

    // 获取值
    get(key) {
        let index = this.hash(key);
        if (!this.table[index]) return undefined; // 如果桶为空,返回 undefined

        // 查找链表中的键值对
        for (let i = 0; i < this.table[index].length; i++) {
            if (this.table[index][i][0] === key) {
                return this.table[index][i][1];
            }
        }
        return undefined; // 如果没有找到,返回 undefined
    }

    // 删除键值对
    delete(key) {
        let index = this.hash(key);
        if (!this.table[index]) return false; // 如果桶为空,返回 false

        for (let i = 0; i < this.table[index].length; i++) {
            if (this.table[index][i][0] === key) {
                this.table[index].splice(i, 1); // 删除链表中的元素
                return true;
            }
        }
        return false; // 如果没有找到,返回 false
    }
}

// 使用示例
let hashTable = new HashTable(10);
hashTable.set('name', 'Alice');
hashTable.set('age', 30);
hashTable.set('city', 'New York');
console.log(hashTable.hash('name')); // 输出 7
console.log(hashTable.hash('age'));  // 输出 1
console.log(hashTable.hash('city')); // 输出 1

console.log(hashTable.get('name')); // 输出 "Alice"
console.log(hashTable.get('age')); // 输出 30
console.log(hashTable.get('city')); // 输出 "New York"
  

三、总结

哈希表是一种高效的数据结构,能够在常数时间内完成查找、插入和删除操作。 希望本文能帮助你更好地理解JavaScript中的哈希表,并在实际项目中灵活运用。