Programacao · conceitos · estruturas de dados
O que e uma hash table?
Uma hash table (tambem chamada hash map) e uma estrutura de dados que armazena pares chave-valor e permite encontrar qualquer valor pela sua chave em, em media, tempo constante - independentemente da quantidade de dados que contem. E uma das estruturas mais uteis de toda a programacao e e o que da poder aos dicionarios e mapas integrados em praticamente todas as linguagens. Depois de ver como funciona, muitos momentos de "como e que isto e tao rapido?" passam a fazer sentido.
O problema que resolve
Imagine armazenar uma lista telefonica como uma simples lista. Para encontrar uma pessoa, pode ter de percorrer cada entrada - um trabalho lento que fica mais lento a medida que a lista cresce, uma operacao O(n). A promessa de uma hash table e diferente: da-lhe a chave e ela salta mais ou menos diretamente para o valor, sem percorrer nada. E essa a diferenca entre verificar cada entrada e saber exatamente onde procurar.
Como funciona: a hash function e os buckets
Por baixo, uma hash table e suportada por um array de posicoes chamadas buckets. O ingrediente magico e a hash function: pega na sua chave e transforma-a num numero, que e mapeado para um indice nesse array.
index = hash(key) % number_of_buckets Para armazenar um valor, passa a chave pela hash para obter um indice e coloca o valor nesse bucket. Para le-lo de volta, passa a mesma chave pela hash outra vez, chega ao mesmo indice e recolhe o valor. Como calcular a hash e indexar um array sao ambos passos rapidos e de custo fixo, as pesquisas nao ficam mais lentas a medida que a tabela cresce. E esse o truque todo.
Colisoes e como sao tratadas
Duas chaves diferentes podem ter hash para o mesmo bucket. Isso chama-se colisao e toda a hash table real tem de lidar com isso. Existem duas estrategias comuns:
- Chaining: cada bucket contem uma pequena lista, e as entradas em colisao sao armazenadas juntas nessa lista. As pesquisas verificam depois a lista (normalmente muito curta) no bucket correto.
- Open addressing: se um bucket estiver ocupado, a tabela procura a proxima posicao livre segundo uma regra fixa, e as pesquisas seguem a mesma regra.
Com uma boa hash function e buckets suficientes, as colisoes mantem-se raras e essas listas mantem-se minusculas, pelo que as pesquisas permanecem rapidas.

E quanto ao desempenho?
E aqui que as hash tables brilham, e onde vive a ressalva honesta. Em media, insercao, pesquisa e remocao sao todas O(1) - tempo constante. No pior caso, se uma ma hash function ou uma entrada hostil despejar todas as chaves num unico bucket, essas operacoes degradam-se para O(n), porque volta a percorrer uma unica lista longa. As boas implementacoes evitam isto usando hash functions solidas e fazendo resizing (rehashing para um array maior) quando a tabela fica demasiado cheia, o que mantem o desempenho num O(1) amortizado. Se quiser rever esta notacao, consulte o nosso guia sobre notacao Big O.
Onde ja usa uma
Usa hash tables constantemente, muitas vezes sem lhes dar nome. Os tipos dicionario e mapa na maioria das linguagens sao hash tables por baixo: Python dict, Java HashMap, JavaScript Map e objeto, Ruby Hash, Go map. Sao tambem a ferramenta de eleicao para caches, para eliminar duplicados e para contar ocorrencias. A otimizacao classica de transformar uma pesquisa lenta com ciclos aninhados numa rapida - baixando de O(n²) para O(n) - e quase sempre feita substituindo varreduras repetidas por uma pesquisa em hash table.
Os compromissos
- Rapida, mas sem ordem. Uma hash table basica nao mantem as chaves em qualquer ordem ordenada ou de insercao (embora algumas versoes de linguagem acrescentem ordenacao por cima).
- Usa memoria extra. Manter as colisoes raras significa manter buckets sobresselentes, pelo que uma hash table troca alguma memoria pela sua velocidade.
- O pior caso e real. O O(1) e uma media; uma entrada adversarial pode forcar o caminho lento, o que importa para codigo sensivel a seguranca.
FAQ
Uma hash table e o mesmo que um dicionario? Em termos do dia a dia, sim - um dicionario ou mapa e a ideia geral (chave para valor), e uma hash table e a forma mais comum de o implementar. Quando alguem diz Python "dict" ou Java "HashMap", esta a usar uma hash table.
Porque e que a pesquisa e O(1) em media? Porque calcula a hash da chave e indexa diretamente num array, em vez de percorrer entradas. Ambos os passos levam tempo constante independentemente de quantos itens estao armazenados, pelo que o custo medio nao cresce com os dados.
O que e uma colisao? Quando duas chaves diferentes tem hash para o mesmo bucket. E normal e esperado; as hash tables tratam disso com chaining ou open addressing, e mantem-na rara com uma boa hash function e resizing.
Quando nao devo usar uma hash table? Quando precisa das chaves mantidas em ordem ordenada, ou de consultas por intervalo ordenado - uma estrutura baseada em arvore encaixa melhor. Tambem quando a memoria e extremamente limitada, ja que as hash tables mantem espaco sobresselente para se manterem rapidas.