Tenho uma pergunta com hash_map
e map
em C ++. Eu entendo que map
está em STL, mas hash_map
não é um padrão. Qual a diferença entre os dois?
117
Eles são implementados de maneiras muito diferentes.
hash_map
( unordered_map
em TR1 e Boost; use-os em vez disso) use uma tabela hash onde a chave é hash para um slot na tabela e o valor é armazenado em uma lista vinculada a essa chave.
map
é implementado como uma árvore de pesquisa binária balanceada (geralmente uma árvore vermelha / preta).
Um unordered_map
deve ter um desempenho ligeiramente melhor para acessar elementos conhecidos da coleção, mas um map
terá características adicionais úteis (por exemplo, ele é armazenado em ordem classificada, o que permite a travessia do início ao fim). unordered_map
será mais rápido na inserção e exclusão do que a map
.
hash_map
foi uma extensão comum fornecida por muitas implementações de biblioteca. É exatamente por isso que foi renomeado paraunordered_map
quando foi adicionado ao padrão C ++ como parte do TR1. map é geralmente implementado com uma árvore binária balanceada como uma árvore vermelha e preta (as implementações variam, é claro).hash_map
eunordered_map
geralmente são implementados com tabelas de hash. Portanto, a ordem não é mantida.unordered_map
inserir / excluir / consultar será O (1) (tempo constante), onde map será O (log n), onde n é o número de itens na estrutura de dados. Entãounordered_map
é mais rápido, e se você não se preocupa com a ordem dos itens deve dar preferênciamap
. Às vezes você quer manter a ordem (ordenada pela chave) e para issomap
seria a escolha.fonte
Algumas das principais diferenças estão nos requisitos de complexidade.
A
map
requerO(log(N))
tempo para inserir e localizar operações, pois é implementado como uma estrutura de dados Red-Black Tree .Um
unordered_map
requer um tempo 'médio' deO(1)
para inserções e descobertas, mas pode ter um tempo de pior caso deO(N)
. Isso ocorre porque é implementado usando a estrutura de dados Hash Table .Então, normalmente,
unordered_map
será mais rápido, mas dependendo das chaves e da função hash que você armazena, pode ficar muito pior.fonte
A especificação C ++ não diz exatamente qual algoritmo você deve usar para os contêineres STL. No entanto, ele impõe certas restrições ao desempenho deles, o que exclui o uso de tabelas hash para
map
e outros contêineres associativos. (Eles são mais comumente implementados com árvores vermelhas / pretas.) Essas restrições requerem melhor desempenho de pior caso para esses contêineres do que as tabelas de hash podem fornecer.Muitas pessoas realmente querem tabelas de hash, portanto, os contêineres associativos STL baseados em hash têm sido uma extensão comum por anos. Consequentemente, eles adicionaram
unordered_map
e tal a versões posteriores do padrão C ++.fonte
map
é geralmente uma árvore balanceada devido ao usooperator<()
como meio de determinar a localização.map
é implementado a partir debalanced binary search tree
(geralmente arb_tree
), uma vez que todo o membro embalanced binary search tree
é classificado, assim como o mapa;hash_map
é implementado a partir de.hashtable
Visto que todo o membro emhashtable
não está classificado, os membros emhash_map(unordered_map)
não são classificados.hash_map
não é uma biblioteca padrão c ++, mas agora é renomeada paraunordered_map
(você pode pensar nela renomeada) e se torna a biblioteca padrão c ++ desde c ++ 11 veja esta questão Diferença entre hash_map e unordered_map? para mais detalhes.Abaixo, apresentarei algumas interfaces básicas do código-fonte de como o mapa de dois tipos é implementado.
mapa:
O código abaixo é apenas para mostrar que, map é apenas um envoltório de um
balanced binary search tree
, quase toda a sua função é apenas invocar abalanced binary search tree
função.hash_map
:hash_map
é implementado dehashtable
cuja estrutura é mais ou menos assim:No código abaixo, darei a parte principal do
hashtable
e, em seguida,hash_map
.Como
map's
apenas um membro érb_tree
, ohash_map's
único membro éhashtable
. É o código principal abaixo:A imagem abaixo mostra quando um hash_map tem 53 buckets, e insere alguns valores, sua estrutura interna.
A imagem abaixo mostra algumas diferenças entre map e hash_map (unordered_map), a imagem vem de Como escolher entre map e unordered_map? :
fonte
Eu não sei o que dá, mas, hash_map leva mais de 20 segundos para limpar () 150K chaves inteiras não assinadas e valores flutuantes. Estou apenas executando e lendo o código de outra pessoa.
É assim que inclui hash_map.
Eu li isso aqui https://bytes.com/topic/c/answers/570079-perfomance-clear-vs-swap
dizendo que clear () é a ordem de O (N). Isso pra mim é muito estranho, mas é assim que é.
fonte