数据结构与算法之字典和散列表(Dictionary 和 HashTable)

50 阅读2分钟

一. 字典

1. 概念

字典是一种以 键-值对 形式存储数据的数据格式,其中键名用来查询特定元素。

**2. 字典和集合有什么异同?

相同点:

都是用来存储不同元素的数据格式;

不同点:

集合是以 值-值 的数据格式存储,而字典是以 键-值 的数据格式存储。

实现:

class Dictionary {
    constructor() {
        this.items = {};
    }
    // 添加项
    set(key, value) {
        this.items[key] = value;
    }
    // 获取对应的项
    get(key) {
        return this.items[key];
    }
    // 移除对应的项
    remove(key) {
        delete this.items[key];
    }
    // 获取所有项对应键的集合
    get keys() {
        return Object.keys(this.items);
    } 
    // 获取所有项对应值的集合
    get values() {
        /*
        也可以使用ES7中的values方法
        return Object.values(this.items)
        */
        // 在这里我们通过循环生成一个数组并输出
        return Object.keys(this.items).reduce((r, c, i) => {
            r.push(this.items[c]);
            return r;
        }, []);
    }
}
const dictionary = new Dictionary();
dictionary.set("Gandalf", "gandalf@email.com");
dictionary.set("John", "johnsnow@email.com");
dictionary.set("Tyrion", "tyrion@email.com");

console.log(dictionary);
console.log(dictionary.keys);
console.log(dictionary.values);
console.log(dictionary.items);

二. 散列表和散列函数

1. 概念

哈希表( Hashtable,也叫散列表),是根据关键码值(·Key value·)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表

**2. 散列表的特点

数组和链接优点的结合,查询速度非常的快,几乎是O(1)的时间复杂度,并且插入和删除也容易。

实现

class HashTable {
  constructor() {
    this.table = [];
  }
  /**
   * 散列函数
   * @param {*} key 键名
   */
  hashCode(key) {
    let hash = 0;
    for (let i = 0; i < key.length; ++i) {
      hash += key.charCodeAt(i);
    }
    return hash % 37;
  }
  /**
   * 向散列表增加/更新一个新的项
   * @param {*} key 添加的键名
   * @param {*} value 添加的值
   */
  put(key, value) {
    let position = this.hashCode(key);
    this.table[position] = value;
  }
  /**
   * 根据键值从散列表中移除值
   * @param {*} key 移除的键名
   * @return {Boolean} 是否成功移除
   */
  remove(key) {
    if (!key) return false;
    let position = this.hashCode(key);
    this.table[position] = undefined;
    return true;
  }

  /**
   * 根据键值检索到特定的值
   * @param {*} key 查找的键名
   * @return {*} 查找的值
   */
  get(key) {
    let position = this.hashCode(key);
    return this.table[position];
  }

  /**
   * 打印散列表中已保存的值
   * @return {*} 散列表的值
   */
  print() {
    return this.table;
  }
}