Подтвердить что ты не робот

Внедрение HashMap

Как сделать создание Hashmap в C с нуля? Какими будут параметры, которые будут приняты во внимание, и как вы проверите хэш-карту относительно того, насколько она хороша? Как и в том, что будет тестовыми примерами тестов, которые вам нужно выполнить, прежде чем вы скажете, что ваша хэш-карта завершена.

4b9b3361

Ответ 1

Ну, если вы знаете основы, стоящие за ними, это не должно быть слишком сложно.

Обычно вы создаете массив с именем "buckets", содержащий ключ и значение, с необязательным указателем для создания связанного списка.

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

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

Проверьте эту быструю реализацию хеш-таблицы:

https://attractivechaos.wordpress.com/2009/09/29/khash-h/

Ответ 2

Лучший подход зависит от ожидаемого распределения ключей и количества коллизий. Если ожидается относительно небольшое количество столкновений, то не имеет значения, какой метод используется. Если ожидается множество коллизий, то, какие из них использовать, зависит от стоимости перефразирования или зондирования и манипулирования структурой расширяемых сегментов данных.

Но вот пример исходного кода реализации An Hashmap в C

Ответ 3

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

  • Отдельная цепочка: одна с массивом ведер (связанных списков)
  • Открытая адресация: один массив, выделенный дополнительным пространством, поэтому столкновение индекса может быть разрешено путем помещения записи в соседний слот.

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

Hashmaps с использованием открытой адресации имеют потенциальные преимущества производительности, когда коэффициент нагрузки поддерживается ниже определенного порога (обычно около 0,7) и используется достаточно хорошая хеш-функция. Это связано с тем, что они избегают возможных промахов в кэше и многих небольших распределений памяти, связанных со связанным списком, и выполняют все операции в смежном массиве, предварительно выделенном. Итерация через все элементы также дешевле. Улавливание hashmaps с использованием открытой адресации должно быть перераспределено до более крупного размера и перефразировано для поддержания идеального коэффициента загрузки, или они сталкиваются со значительным снижением производительности. Коэффициент их загрузки не может превышать 1,0.

Некоторые ключевые показатели производительности для оценки при создании хэш-карты будут включать:

  • Максимальный коэффициент загрузки
  • Среднее количество столкновений при вставке
  • Распределение столкновений: неравномерное распределение (кластеризация) может указывать на слабую хэш-функцию.
  • Относительное время для различных операций: put, get, remove существующих и несуществующих записей.

Вот гибкая реализация hashmap, которую я сделал. Я использовал открытую адресацию и линейное зондирование для разрешения конфликтов.

https://github.com/DavidLeeds/hashmap

Ответ 4

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

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

Лучший способ реализовать это - сначала подумать обо всех этих параметрах, а затем не закодировать его самостоятельно, а выбрать зрелую существующую реализацию. В Google есть несколько хороших реализаций - например, http://code.google.com/p/google-sparsehash/