创建一个地图(Map)数据结构,创建一个哈希表 (Hash Table)

353 阅读3分钟

创建一个地图(Map)数据结构

接下来将涵盖地图和哈希表。地图是存储键值对的数据结构。在JavaScript中,这些都是作为对象提供给我们的。地图提供了基于键值的存储项目的快速查找,是非常常见和有用的数据结构。

让我们来练习一下创建我们自己的地图。因为JavaScript对象提供的地图结构比我们在这里写的任何东西都要有效得多,这主要是作为一种学习练习。然而,JavaScript对象只为我们提供了某些操作。如果我们想定义自定义操作呢?使用这里提供的Map对象作为JavaScript对象的包装物。在Map对象上创建以下方法和操作。

  • add 接受一个键,值对来添加到地图中。
  • remove 接受一个键并删除相关的键、值对
  • get 接受一个键并返回存储的值
  • has 接受一个键,如果该键存在则返回true,如果不存在则返回false。
  • values 返回map中所有值的一个数组。
  • size 返回地图中项目的数量
  • clear清空地图
var Map = function() {
  this.collection = {};

this.has = (key) => {
    return this.collection.hasOwnProperty(key);
  };

  this.add = (key, value) => {
    // Note, this can also be used to update a value
    this.collection[key] = value;
  };

  this.remove = (key) => {
    if (this.has(key)) {
      delete this.collection[key];
    }
  };

  this.get = (key) => { 
    if (this.has(key)) {
      return this.collection[key];
    } else {
      // Note, collection[someMissingKey] is already undefined
      return undefined;
    }
  };

  this.values = () => {  
    return [...Object.values(this.collection)];
  };

  this.size = () => {
    return Object.entries(this.collection).length;
  };

  this.clear = () => {
    this.collection = {};
  };
};

创建一个哈希表

我们将学习哈希表。哈希表用于实现关联数组,或者键值对的映射,就像我们刚刚学习的对象和地图一样。例如,一个JavaScript对象可以被实现为一个哈希表(它的实际实现将取决于它的运行环境)。哈希表的工作方式是,它接受一个键的输入,并以一种确定的方式将这个键散列成一些数值。然后这个数值被用作关联值存储的实际密钥。然后,如果你试图再次访问相同的键,散列函数将处理该键,返回相同的数值结果,然后用于查询相关的值。这平均提供了非常有效的O(1)查询时间。

散列表可以被实现为数组,由散列函数在指定范围内产生数组索引。在这种方法中,数组大小的选择很重要,散列函数也是如此。例如,如果散列函数对两个不同的键产生相同的值怎么办?这就是所谓的碰撞。处理碰撞的一种方法是将两个键值对都存储在该索引上。然后,在查找其中一个时,你将不得不在项目桶中进行迭代,以找到你要找的那个键。一个好的散列函数会尽量减少碰撞,以保持有效的搜索时间。

在这里,我们不会关注散列或哈希表实现的细节,我们只是试图了解它们工作的一般意义。

让我们来创建一个哈希表的基本功能。

  1. 你可以向函数hash传递一个字符串值,它将返回一个哈希值,你可以将其作为存储的密钥。
  2. 根据这个哈希值在this.collection对象中存储项目。创建这三个方法:添加、删除和查找
  • 第一个方法应该接受一个键值对来添加到哈希表中。第二个方法应该在传递一个键时删除一个键值对。

  • 第三个方法应该接受一个键并返回相关的值,如果键不存在则返回空值。

  • 请确保在编写代码时考虑到碰撞的问题

let called = 0;

let hash = string => {
  called++;
  var hashed = 0;
  for (var i = 0; i < string.length; i++) {
    hashed += string.charCodeAt(i);
  }
  return hashed;
};

let HashTable = function() {
  this.collection = {};

this.add = (key, value) => {
    const hashedKey = hash(key);
    this.collection[hashedKey] = this.collection[hashedKey] || {};
    this.collection[hashedKey][key] = value;
  }

  this.lookup = (key) => {
    const hashedKey = hash(key);
    return this.collection[hashedKey][key];
  }

  this.remove = (key) => {
    const hashedKey = hash(key);
    delete this.collection[hashedKey][key];
    if (!!Object.keys(this.collection[hashedKey]).length)
      delete this.collection[hashedKey];
  }
};