Как сделать создание Hashmap в C с нуля? Какими будут параметры, которые будут приняты во внимание, и как вы проверите хэш-карту относительно того, насколько она хороша? Как и в том, что будет тестовыми примерами тестов, которые вам нужно выполнить, прежде чем вы скажете, что ваша хэш-карта завершена.
Внедрение HashMap
Ответ 1
Ну, если вы знаете основы, стоящие за ними, это не должно быть слишком сложно.
Обычно вы создаете массив с именем "buckets", содержащий ключ и значение, с необязательным указателем для создания связанного списка.
Когда вы обращаетесь к хеш-таблице с помощью ключа, вы обрабатываете ключ с помощью пользовательской хеш-функции, которая возвращает целое число. Затем вы берете модуль результата, и это место вашего индекса массива или "корзины". Затем вы проверяете ключ без ключа с сохраненным ключом, и если он совпадает, то вы нашли правильное место.
В противном случае вы столкнулись с "коллизией" и должны пролистать связанный список и сравнивать ключи, пока не совпадете. (обратите внимание, что в некоторых реализациях для связывания используется двоичное дерево вместо связанного списка).
Проверьте эту быструю реализацию хеш-таблицы:
Ответ 2
Лучший подход зависит от ожидаемого распределения ключей и количества коллизий. Если ожидается относительно небольшое количество столкновений, то не имеет значения, какой метод используется. Если ожидается множество коллизий, то, какие из них использовать, зависит от стоимости перефразирования или зондирования и манипулирования структурой расширяемых сегментов данных.
Но вот пример исходного кода реализации An Hashmap в C
Ответ 3
Основная цель хэш-карты состоит в том, чтобы хранить набор данных и обеспечивать постоянный поиск по времени с помощью уникального ключа. Существуют два общих стиля реализации hashmap:
- Отдельная цепочка: одна с массивом ведер (связанных списков)
- Открытая адресация: один массив, выделенный дополнительным пространством, поэтому столкновение индекса может быть разрешено путем помещения записи в соседний слот.
Отдельная цепочка предпочтительнее, если хэш-карта может иметь слабую хеш-функцию, нежелательно предварительно распределять память для потенциально неиспользуемых слотов, или записи могут иметь переменный размер. Этот тип hashmap может продолжать функционировать относительно эффективно, даже если коэффициент загрузки превышает 1,0. Очевидно, что в каждой записи требуется дополнительная память для хранения указателей связанных списков.
Hashmaps с использованием открытой адресации имеют потенциальные преимущества производительности, когда коэффициент нагрузки поддерживается ниже определенного порога (обычно около 0,7) и используется достаточно хорошая хеш-функция. Это связано с тем, что они избегают возможных промахов в кэше и многих небольших распределений памяти, связанных со связанным списком, и выполняют все операции в смежном массиве, предварительно выделенном. Итерация через все элементы также дешевле. Улавливание hashmaps с использованием открытой адресации должно быть перераспределено до более крупного размера и перефразировано для поддержания идеального коэффициента загрузки, или они сталкиваются со значительным снижением производительности. Коэффициент их загрузки не может превышать 1,0.
Некоторые ключевые показатели производительности для оценки при создании хэш-карты будут включать:
- Максимальный коэффициент загрузки
- Среднее количество столкновений при вставке
- Распределение столкновений: неравномерное распределение (кластеризация) может указывать на слабую хэш-функцию.
- Относительное время для различных операций: put, get, remove существующих и несуществующих записей.
Вот гибкая реализация hashmap, которую я сделал. Я использовал открытую адресацию и линейное зондирование для разрешения конфликтов.
Ответ 4
Существуют и другие механизмы обработки переполнения, чем простой сопоставленный список записей переполнения, например, отнимает много памяти.
Какой механизм использовать, помимо прочего, зависит, если вы можете выбрать хеш-функцию и возможно выбрать более одного (для реализации, например, двойного хэширования для обработки конфликтов); если вы ожидаете часто добавлять предметы или если карта статична после заполнения; если вы намерены удалить предметы или нет;...
Лучший способ реализовать это - сначала подумать обо всех этих параметрах, а затем не закодировать его самостоятельно, а выбрать зрелую существующую реализацию. В Google есть несколько хороших реализаций - например, http://code.google.com/p/google-sparsehash/