У меня вопрос hash_map
и map
по C ++. Я понимаю, что map
это в STL, но hash_map
это не стандарт. В чем разница между ними?
117
Реализованы они очень по-разному.
hash_map
( unordered_map
в TR1 и Boost; используйте их вместо) используйте хеш-таблицу, в которой ключ хешируется в слот в таблице, а значение сохраняется в списке, привязанном к этому ключу.
map
реализован как сбалансированное двоичное дерево поиска (обычно красное / черное дерево).
unordered_map
Должны дать немного более высокую производительность для доступа к известным элементам коллекции, но map
будет иметь дополнительные полезные свойства (например , они хранятся в отсортированном порядке, что позволяет обход от начала до конца). unordered_map
будет быстрее вставлять и удалять, чем map
.
hash_map
было распространенным расширением, предоставляемым многими реализациями библиотек. Именно поэтому его переименовали в,unordered_map
когда он был добавлен в стандарт C ++ как часть TR1. map обычно реализуется с помощью сбалансированного двоичного дерева, такого как красно-черное дерево (реализации, конечно, различаются).hash_map
иunordered_map
обычно реализуются с помощью хеш-таблиц. Таким образом, порядок не поддерживается.unordered_map
insert / delete / query будет O (1) (постоянное время), где map будет O (log n), где n - количество элементов в структуре данных. Такunordered_map
работает быстрее, и если вам не важен порядок элементов, то предпочтение следует отдаватьmap
. Иногда вы хотите поддерживать порядок (упорядоченный по ключу), и этоmap
будет выбор.источник
Некоторые из ключевых отличий заключаются в требованиях к сложности.
A
map
требуетO(log(N))
времени для операций вставки и поиска, поскольку он реализован в виде структуры данных Red-Black Tree .Для вставки и поиска
unordered_map
требуется «среднее» времяO(1)
, но разрешено иметь наихудшее времяO(N)
. Это потому, что он реализован с использованием структуры данных Hash Table .Обычно
unordered_map
это будет быстрее, но в зависимости от ключей и хэш-функции, которые вы храните, может стать намного хуже.источник
Спецификация C ++ не говорит точно, какой алгоритм вы должны использовать для контейнеров STL. Однако это накладывает определенные ограничения на их производительность, что исключает использование хеш-таблиц для
map
и других ассоциативных контейнеров. (Чаще всего они реализуются с помощью красно-черных деревьев.) Эти ограничения требуют для этих контейнеров более высокой производительности в худшем случае, чем могут обеспечить хэш-таблицы.Однако многим людям действительно нужны хеш-таблицы, поэтому ассоциативные контейнеры STL на основе хешей уже много лет являются обычным расширением. Следовательно, они добавили
unordered_map
и тому подобное в более поздние версии стандарта C ++.источник
map
том, что обычно сбалансированное btree было связано с использованиемoperator<()
в качестве средства определения местоположения.map
реализуется изbalanced binary search tree
(обычно arb_tree
), поскольку все членыbalanced binary search tree
сортируются так, как map;hash_map
реализуется изhashtable
.S Поскольку всеhashtable
члены вhash_map(unordered_map)
не отсортированы, поэтому члены в не сортируются.hash_map
не является стандартной библиотекой С ++, но теперь она переименована вunordered_map
(вы можете подумать о ее переименовании) и становится стандартной библиотекой С ++, так как С ++ 11 см. этот вопрос Разница между hash_map и unordered_map?для более подробной информации.Ниже я приведу базовый интерфейс из исходного кода, показывающий, как реализована карта двух типов.
карта:
Приведенный ниже код просто показывает, что map - это просто оболочка
balanced binary search tree
, почти вся ее функция - это просто вызватьbalanced binary search tree
функцию.hash_map
:hash_map
реализованhashtable
, структура которого выглядит примерно так:В приведенном ниже коде я приведу основную часть
hashtable
, а затем дамhash_map
.Как
map's
только членrb_tree
,hash_map's
единственный членhashtable
. Это основной код, как показано ниже:На изображении ниже показано, когда hash_map имеет 53 сегмента и вставляет некоторые значения, это внутренняя структура.
На изображении ниже показана некоторая разница между картой и hash_map (unordered_map), изображение взято из Как выбрать между картой и unordered_map? :
источник
Я не знаю, что дает, но hash_map требуется более 20 секунд для clear () 150K целочисленных ключей без знака и значений с плавающей запятой. Я просто бегаю и читаю чужой код.
Вот как он включает hash_map.
Я прочитал это здесь https://bytes.com/topic/c/answers/570079-perfomance-clear-vs-swap
говоря, что clear () является порядком O (N). Для меня это очень странно, но так оно и есть.
источник