Разборка одного момента в хеш-таблице

239
10 октября 2017, 04:47

Есть код, не могу разобраться как работает put в классе HashMap() Разъясните мне пожалуйста... На сколько я понял мы обращаемся к put и передаем ключ елемента и само число. Потом ищем остаток ключ+сам объем списка. Зачем он нужен этот остаток ?. С while первое условие понятное, вроде как, а вот со вторым не пойму, зачем нужен указатель ключа??.. hash = (hash + 1) % TABLE_SIZE; и что мы получаем(какую пользу от элемента выше)?

class HashEntry {
    private:
          int key;
          int value;
    public:
          HashEntry(int key, int value) {
                this->key = key;
                this->value = value;
          }
          int getKey() {
                return key;
          }
          int getValue() {
                return value;
          }
    };
    const int TABLE_SIZE = 129;
    class HashMap {
    private:
          HashEntry **table;
    public:
          HashMap() {
                table = new HashEntry*[TABLE_SIZE];
                for (int i = 0; i < TABLE_SIZE; i++)
                      table[i] = NULL;
          }
          int get(int key) {
                int hash = (key % TABLE_SIZE);
                while (table[hash] != NULL && table[hash]->getKey() != key)
                      hash = (hash + 1) % TABLE_SIZE;
                if (table[hash] == NULL)
                      return -1;
                else
                      return table[hash]->getValue();
          }
          void put(int key, int value) {
                int hash = (key % TABLE_SIZE);
                while (table[hash] != NULL && table[hash]->getKey() != key)
                      hash = (hash + 1) % TABLE_SIZE;
                if (table[hash] != NULL)
                      delete table[hash];
                table[hash] = new HashEntry(key, value);
          }
          ~HashMap() {
                for (int i = 0; i < TABLE_SIZE; i++)
                      if (table[i] != NULL)
                            delete table[i];
                delete[] table;
          }
    };
Answer 1

HashMap реализует простейшее отображение ключ->значение используя хэш таблицу. Метод put предназначен для добавление int значения по int ключу. Вначале с помощью int hash = (key % TABLE_SIZE); мы получаем индекс возможного места в таблице, куда нужно разместить ключ и значение, берётся остаток от деления чтобы во-первых индекс вмещался в размер таблицы, во-вторых чтобы при равновероятном распределении ключей они попадали равномерно на всю таблицу. В настоящих реализациях хеш таблиц на самом деле ключ нужно хешировать через какой-то быстрый алгоритм аналогичный например CRC32, т.е. index = CRC32(key) % TABLE_SIZE, в нашем примере как понимаю простейшая демо реализация хеш таблиц. Далее от найденного индекса мы двигаемся вперёд пока либо место занято либо ключ отличается у хранимого элемента, движение вперёд идёт за счёт hash = (hash + 1) % TABLE_SIZE;, остаток от деления нужен чтобы начать с начала если мы дошли до конца таблицы. Т.е. получается в хеш таблице вначале примерно попадаем на случайное место а потом ищем себе место подходящее вблизи стартового индекса, место которое ещё не занято. Т.к. разные ключи могут иметь одинаковый хеш и значит одинаковый стартовый индекс, поэтому нужно продвинуться на соседние пустые места, это называется разрешением коллизий, т.е. когда два ключа попали в одну ячейку нужно как-то решить эту проблему (в нашем случаее это продвижение на ближайшее свободное место). Далее если table[hash] != NULL это означает что мы нашли элемент с тем же ключом, тогда его удаляем (delete table[hash];) чтобы разместить поверх новый. На найденное свободное место теперь размещаем новую пару ключ/значение table[hash] = new HashEntry(key, value);.

READ ALSO
Работа с очередями в С++

Работа с очередями в С++

Нужно написать программу, которая в заданном порядке выводит звезды на форму и совершает их перемещение в том же порядке, одну за другойЗадачу...

206
Статические переменные и методы класса

Статические переменные и методы класса

Как в современном (c++11 и более позднем) объявлять статические переменные в классе и можно ли вообще это делать?

217
Логика в майнере nheqminer

Логика в майнере nheqminer

Есть задание, написать свой майнер, за основу взяли https://githubcom/nicehash/nheqminer, для тестов выбрал nanopool, использую библиотеку "boost"

228
Ошибка &ldquo;Файл не найден&rdquo; Qt Creator

Ошибка “Файл не найден” Qt Creator

Написал несложную программу на с++ в Qt CreatorПрограмма работала

198