Рубрики
Без рубрики

JavaScript Hasth Table – ассоциативный массив хеширования в JS

Хэш-таблицы являются структурой данных, которые позволяют создать список парных значений. Затем вы можете получить определенное значение, используя ключ для этого значения, которое вы переводите в таблицу заранее. Хэш-таблица преобразует ключ в целочисленный индекс, используя хеш

Автор оригинала: FreeCodeCamp Community Member.

Хэш-таблицы являются структурой данных, которые позволяют создать список парных значений. Затем вы можете получить определенное значение, используя ключ для этого значения, которое вы переводите в таблицу заранее.

HASH TABLE преобразует ключ в целочисленный индекс с использованием хеш-функции, и индекс решит, где хранить пару ключ/значение в памяти:

Вы обычно используете хеш-таблица из-за его быстрого поиска, вставки и удаления операций:

Алгоритм Худший случай В среднем
Космос На) На)
Поиск На) O (1)
Вставлять На) O (1)
Удалить На) O (1)

Источник от Википедия

В этом руководстве помогут вам понять реализацию Hash Table в JavaScript, а также как вы можете построить свой собственный класс Hash Status.

Во-первых, давайте посмотрим на JavaScript’s Объект и Карта классы.

Как использовать хеш-таблицы с объектом и классами карты в JavaScript

Наиболее распространенным примером хэш-таблица в JavaScript является Объект Тип данных, где вы можете сопрянуть значение свойства объекта с помощью ключа свойств.

В следующем примере ключевой Натан Сообщено со значением телефона номера "555-0182" и ключ Джейн в паре со значением "315-0322" :

let obj = {
  Nathan: "555-0182",
  Jane: "315-0322"
}

Но JavaScript’s Объект Тип – это особый вид реализации хэш-таблицы по двум причинам:

  • У него есть свойства, добавленные Объект класс. Клавиши, которые вы вводите, могут конфликтуйте и перезаписать свойства по умолчанию, унаследованные от класса.
  • Размер хеш-стола не отслеживается. Вам необходимо вручную подсчитать, сколько свойств определяется программистом, а не унаследованным от прототипа.

Например, Объект Прототип имеет HasownProperty () Метод, который позволяет проверить, не наследуется свойство:

const obj = {};
obj.name = "Nathan";

console.log(obj.hasOwnProperty("name")); // true

JavaScript не заблокирует попытку перезаписать HasownProperty () Метод, который может вызвать в такой ошибке:

const obj = {};
obj.name = "Nathan";
obj.hasOwnProperty = true;

console.log(obj.hasOwnProperty("name")); 
// Error: obj.hasOwnProperty is not a function

Чтобы справиться с этими недостатками, JavaScript создал еще одну реализацию структуры данных HASH Table, которая называется карта

Так же, как Объект , Карта Позволяет хранить пары клавишных значений внутри структуры данных. Вот пример Карта в действии:

const collection = new Map();

collection.set("Nathan", "555-0182");
collection.set("Jane", "555-0182");

console.log(collection.get("Nathan")); // 555-0182
console.log(collection.size); // 2

В отличие от Объект Тип, Карта требует, чтобы вы использовали Установить () и Получить () Методы для определения и получения любых значений клавишных пар, которые вы хотите быть добавлены в структуру данных.

Вы также не можете перезаписать Карта Унаследованные свойства. Например, следующий код пытался перезаписать Размер Значение свойств до ложь :

const collection = new Map();

collection.set("Nathan", "555-0182");
collection["size"] = false;

console.log(collection.get("size")); // undefined
console.log(collection.size); // 1

Как вы можете видеть из кода выше, вы не можете добавить новую запись в Карта объект без использования Установить () метод.

Карта Структура данных также является имитена, что означает, что вы можете включить петлю по данным следующим образом:

const myMap = new Map();

myMap.set("Nathan", "555-0182");
myMap.set("Jane", "315-0322");

for (let [key, value] of myMap) {
  console.log(`${key} = ${value}`);
}

Теперь, когда вы узнали, как JavaScript реализует хэш-таблицы в виде Объект и Карта Структуры данных, давайте посмотрим, как вы можете создать собственную реализацию HASH Table.

Как реализовать структуру данных хеш-таблицы в JavaScript

Хотя JavaScript уже имеет два реализация хэш-таблицы, написание собственной реализации HASH Table, является одним из наиболее распространенных вопросов собеседования JavaScript.

Вы можете реализовать хеш-таблица в JavaScript на три этапа:

  • Создать Hashtable класс с Таблица и Размер начальные свойства
  • Добавить хеш () Функция для преобразования ключей в индексы
  • Добавьте Установить () и Получить () Методы добавления и извлечения пар клавиши/значения из таблицы.

Хорошо, давайте начнем с создания Hashtable класс. Код ниже создаст Таблица ведра с размером 127 :

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

Все ваши пары ключа/значения будут храниться внутри Таблица имущество.

Как написать метод HASH ()

Далее вам нужно создать хеш () Метод, который примет ключ значение и преобразовать его в индекс.

Простой способ создания хеша было бы суммировать код ASCII символов в клавиши, используя Carcodeat () Метод следующим образом. Обратите внимание, что метод называется использованием _ Чтобы указать, что это частный класс:

_hash(key) {
  let hash = 0;
  for (let i = 0; i < key.length; i++) {
    hash += key.charCodeAt(i);
  }
  return hash;
}

Но так как Hashtable Участок имеет только 127 ведер, это означает, что _hash () Метод должен вернуть номер между 0 и 127 Отказ

Чтобы гарантировать, что значение HASH не превышает размер ведра, вам необходимо использовать оператор модуля, как показано ниже:

_hash(key) {
  let hash = 0;
  for (let i = 0; i < key.length; i++) {
    hash += key.charCodeAt(i);
  }
  return hash % this.table.length;
}

Теперь, когда у вас есть _hash () Метод завершен, пришло время написать Установить () и Получить () методы.

Как написать метод SET ()

Чтобы установить пару ключ/Value в своем хэш-таблице, вам нужно написать Установить () Метод, который принимает (ключ, значение) Как его параметры:

  • Установить () Метод позвонит _hash () метод, чтобы получить индекс значение.
  • [ключ, значение] Пара будет назначена на Таблица По указанным индекс
  • Тогда Размер Собственность будет увеличиваться одним
set(key, value) {
  const index = this._hash(key);
  this.table[index] = [key, value];
  this.size++;
}

Теперь, когда Установить () Метод завершен, давайте напишем Получить () метод для получения значения на его ключ.

Как написать метод Get ()

Чтобы получить определенное значение из хеш-стола, вам нужно написать Получить () Метод, который принимает ключ Значение как его параметр:

  • Метод позвонит _hash () Способ еще раз извлечь таблицу индекс
  • Верните значение, хранящееся в Таблица [индекс]
get(key) {
  const index = this._hash(key);
  return this.table[index];
}

Таким образом, Получить () Способ вернет либо пару ключа/значения, либо undefined Когда нет пары ключа/значения, сохраненной в указанном индекс Отказ

Все идет нормально. Добавим еще один метод, чтобы удалить пару ключа/значения из хеш-таблица рядом.

Как написать метод удаления ()

Чтобы удалить пару ключ/значение из таблицы HASH, вам нужно написать Удалить () Метод, который принимает ключ Значение как его параметр:

  • Получить право индекс используя _hash () метод
  • Проверьте, если Таблица [индекс] имеет правдовую ценность и Длина Собственность больше нуля. Назначить . undefined ценность справа индекс и уменьшение Размер свойство на один, если это так.
  • Если нет, просто верните ложный
remove(key) {
  const index = this._hash(key);

  if (this.table[index] && this.table[index].length) {
    this.table[index] = undefined;
    this.size--;
    return true;
  } else {
    return false;
  }
}

С этим у вас сейчас есть работа Удалить () метод. Давайте посмотрим, если Hashtable класс работает правильно.

Как проверить реализацию Hash Table

Пришло время проверить реализацию хэш-таблицы. Вот полный код для реализации хеш-таблицы снова:

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

  _hash(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash += key.charCodeAt(i);
    }
    return hash % this.table.length;
  }

  set(key, value) {
    const index = this._hash(key);
    this.table[index] = [key, value];
    this.size++;
  }

  get(key) {
    const target = this._hash(key);
    return this.table[target];
  }

  remove(key) {
    const index = this._hash(key);

    if (this.table[index] && this.table[index].length) {
      this.table[index] = [];
      this.size--;
      return true;
    } else {
      return false;
    }
  }
}

Чтобы проверить Hashtable Класс, я собираюсь создать новый экземпляр Класс и установите некоторые пары клавиш/значение, как показано ниже. Пары ключа/значений ниже представляют собой просто произвольные значения номера в паре с именами стран без какого-либо особого значения:

const ht = new HashTable();
ht.set("Canada", 300);
ht.set("France", 100);
ht.set("Spain", 110);

Тогда давайте постараемся получить их, используя Получить () Метод:

console.log(ht.get("Canada")); // [ 'Canada', 300 ]
console.log(ht.get("France")); // [ 'France', 100 ]
console.log(ht.get("Spain")); // [ 'Spain', 110 ]

Наконец, давайте попробуем удалить одно из этих значений с Удалить () Метод:

console.log(ht.remove("Spain")); // true
console.log(ht.get("Spain")); // undefined

Хорошо, все методы работают, как ожидалось. Давайте попробуем другую вставку с новым Hashtable экземпляр и извлеките эти значения:

const ht = new HashTable();

ht.set("Spain", 110);
ht.set("ǻ", 192);

console.log(ht.get("Spain")); // [ 'ǻ', 192 ]
console.log(ht.get("ǻ")); // [ 'ǻ', 192 ]

Упс! Похоже, мы вошли в некоторые проблемы здесь. 😨.

Как обрабатывать индекс столкновения

Иногда хеш-функция в хэш-столе может вернуть то же самое индекс номер. В тестовом случае выше, строка "Испания" и "ǻ" оба вернуть то же самое хеш ценность Потому что номер 507 это сумма обоих их кода ASCII.

То же самое хеш Значение приведет к тому, что индекс для сталкиваться , перезаписывать предыдущую запись с новым.

Прямо сейчас данные, хранящиеся в нашей реализации Hash Table, выглядят следующим образом:

[
    [ "Spain", 110],
    [ "France", 100]
]

Чтобы обработать индекс Столкновение номера, вам необходимо хранить пару ключа/значения во втором массиве, чтобы конечный результат выглядит следующим образом:

[
    [
        [ "Spain", 110 ],
        [ "ǻ", 192 ]
    ],
    [
        ["France", 100]
    ],
]

Чтобы создать второй массив, вам нужно обновить Установить () Метод так, чтобы он будет:

  • Посмотрите на Таблица [индекс] и петля по значению массива.
  • Если ключ на одной из массивов равен ключ передается на метод, замените значение на индекс 1 и остановить любое дальнейшее исполнение с Возвращение утверждение.
  • Если нет совпадения ключ Найден, нажимайте новый массив ключа и стоимость ко второму массиву.
  • Иногда инициализируйте новый массив и нажмите клавишу/Value Pair до указанного индекс
  • Всякий раз, когда push () Способ называется, увеличивает Размер свойство на один.

Полный Установить () Код метода будет следующим:

set(key, value) {
  const index = this._hash(key);
  if (this.table[index]) {
    for (let i = 0; i < this.table[index].length; i++) {
      // Find the key/value pair in the chain
      if (this.table[index][i][0] === key) {
        this.table[index][i][1] = value;
        return;
      }
    }
    // not found, push a new key/value pair
    this.table[index].push([key, value]);
  } else {
    this.table[index] = [];
    this.table[index].push([key, value]);
  }
  this.size++;
}

Далее обновите Получить () Способ, чтобы он также проверит массив второго уровня с помощью для петля и вернуть правильную пару ключ/значение:

get(key) {
  const target = this._hash(key);
  if (this.table[target]) {
    for (let i = 0; i < this.table.length; i++) {
      if (this.table[target][i][0] === key) {
        return this.table[target][i][1];
      }
    }
  }
  return undefined;
}

Наконец, вам нужно обновить Удалить () Способ так, чтобы он будет петлен по набору второго уровня и удалить массив справа ключ значение, используя Сращивание () Метод:

remove(key) {
  const index = this._hash(key);

  if (this.table[index] && this.table[index].length) {
    for (let i = 0; i < this.table.length; i++) {
      if (this.table[index][i][0] === key) {
        this.table[index].splice(i, 1);
        this.size--;
        return true;
      }
    }
  } else {
    return false;
  }
}

С этим твои Hashtable Класс сможет избежать столкновения любого номера и хранить пару клавиши/значения внутри массива второго уровня.

Как бонус, давайте добавим Дисплей () Метод, который отобразит все пары клавиш/значение, сохраненные в хэш-таблице. Вам просто нужно использовать foreach () Способ повторить за столом и карта () Значения в строку, как показано ниже:

display() {
  this.table.forEach((values, index) => {
    const chainedValues = values.map(
      ([key, value]) => `[ ${key}: ${value} ]`
    );
    console.log(`${index}: ${chainedValues}`);
  });
}

Вот полный Hashtable Коликовый код еще раз с уведомлением столкновения подается для вашей справки:

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

  _hash(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash += key.charCodeAt(i);
    }
    return hash % this.table.length;
  }

  set(key, value) {
    const index = this._hash(key);
    if (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]);
    } else {
      this.table[index] = [];
      this.table[index].push([key, value]);
    }
    this.size++;
  }

  get(key) {
    const index = this._hash(key);
    if (this.table[index]) {
      for (let i = 0; i < this.table.length; i++) {
        if (this.table[index][i][0] === key) {
          return this.table[index][i][1];
        }
      }
    }
    return undefined;
  }

  remove(key) {
    const index = this._hash(key);

    if (this.table[index] && this.table[index].length) {
      for (let i = 0; i < this.table.length; i++) {
        if (this.table[index][i][0] === key) {
          this.table[index].splice(i, 1);
          this.size--;
          return true;
        }
      }
    } else {
      return false;
    }
  }

  display() {
    this.table.forEach((values, index) => {
      const chainedValues = values.map(
        ([key, value]) => `[ ${key}: ${value} ]`
      );
      console.log(`${index}: ${chainedValues}`);
    });
  }
}

Вы можете проверить реализацию, создав новый Hashtable экземпляр и выполните некоторую вставку и удаление:

const ht = new HashTable();

ht.set("France", 111);
ht.set("Spain", 150);
ht.set("ǻ", 192);

ht.display();
// 83: [ France: 111 ]
// 126: [ Spain: 150 ],[ ǻ: 192 ]

console.log(ht.size); // 3
ht.remove("Spain");
ht.display();
// 83: [ France: 111 ]
// 126: [ ǻ: 192 ]

Теперь нет столкновения внутри Hashtable пример. Отличная работа!

Заключение

В этом руководстве вы узнали, что такое хэш-таблицы и как JavaScript использует его для создания Объект и Карта структура данных.

Вы также узнали, как реализовать свой собственный Hashtable Класс, а также о том, как предотвратить столкновение ключевых индексов хеш-стола от столкновения с использованием методики цепочки.

Используя структуру данных HASH Table, вы сможете создать ассоциативный массив с быстрым поиском, вставкой и операциями удаления. 😉.

Спасибо за чтение этого учебника

Если вы хотите узнать больше о JavaScript, вы можете проверить свой сайт на Sebhastian.com, где я опубликовал Более 100 учебных пособий о программировании с JavaScript Все используют простые для понимания объяснений и примеров кода.

Учебники включают в себя строковые манипуляции, манипулирование дату, методы массива и объектов, решения JavaScript Algorithm и многое другое.