Автор оригинала: 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 и многое другое.