Módulo 11 - Tabelas hash: o dicionário por dentro

A função hash: espalhar bem as chaves

8 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 12/07/2026

O que você vai aprender

  • Entender que uma boa função hash é determinística e uniforme.
  • Ver por que amontoar chaves numa posição destrói a velocidade.
  • Reconhecer o que torna uma função hash ruim na prática.
  • Prever o índice gerado por uma função hash simples.

O que faz uma função hash ser boa

A função hash é a peça que faz ou quebra a tabela. Três qualidades definem uma boa função. A primeira é ser determinística: a mesma chave tem que gerar sempre o mesmo índice, em qualquer momento. Se a Ana caísse hoje no escaninho 2 e amanhã no 5, guardar e buscar nunca combinariam. A segunda é ser rápida de calcular, porque o objetivo da estrutura é justamente evitar trabalho; se calcular o índice fosse tão caro quanto varrer a lista, não haveria ganho. A terceira, e a mais delicada, é espalhar bem: chaves diferentes devem cair em posições variadas, de modo que os itens fiquem distribuídos pelo vetor e não empilhados num canto só.

A distribuição uniforme é o que sustenta a promessa de velocidade. Pense de novo no armário de escaninhos. Se a função mandasse todos os moradores para o escaninho 3, aquele escaninho viraria uma pilha enorme e achar uma carta específica exigiria vasculhar a pilha toda, exatamente o que a tabela queria evitar. Com uma função que espalha bem, cada escaninho fica com poucas cartas, e olhar dentro de um escaninho é rápido porque há pouca coisa ali. Uniformidade não significa perfeição, um espalhamento ideal e impossível; significa que, na média, as chaves se distribuem sem grandes montanhas e vales.

Comparação de duas funções hash sobre o mesmo vetor de sete posições. À esquerda, rotulada função ruim, quase todas as chaves apontam para a posição 3, formando uma pilha alta ali e deixando os outros escaninhos vazios. À direita, rotulada função boa, as mesmas chaves estão espalhadas, uma ou duas por escaninho, cobrindo o vetor de forma equilibrada.
Função ruim amontoa tudo num escaninho; função boa espalha as chaves de forma uniforme pelo vetor.

Por dentro de uma função simples

Dá para sentir a diferença com um exemplo. Uma função que só olha a primeira letra do nome espalha mal: muitos nomes brasileiros começam com as mesmas letras, então vários cairiam no mesmo balde. Uma função que soma os códigos de todas as letras e tira o resto pelo tamanho do vetor espalha melhor, porque usa a chave inteira e o resto embaralha os valores. Funções profissionais vão além, misturando os bits da chave com multiplicações e deslocamentos para que até chaves parecidas, como Ana e Ano, terminem longe uma da outra. O princípio, porém, é sempre o mesmo: usar bem a informação da chave e encaixar o resultado na faixa de posições do vetor.

// vetor de 10 posições (índices 0 a 9)
// função: soma dos códigos das letras, resto por 10

FUNÇÃO hash(chave)
  soma <- 0
  PARA cada letra de chave faça
    soma <- soma + codigo(letra)
  fim
  RETORNE soma mod 10
fim

// códigos: R=82 E=69 I=73
// "REI" -> 82 + 69 + 73 = 224
// 224 mod 10 = 4
escreva(hash("REI"))   // 4

A função soma os códigos das letras e tira o resto por 10. O resto é o índice, sempre entre 0 e 9.

🎮 Jogo da aula

Calcule o índice

A função hash soma os códigos das letras e tira o resto por 5. Use os códigos dados para descobrir o índice de SOL.

// códigos: S=83  O=79  L=76
// vetor de 5 posições (resto por 5)

FUNÇÃO hash(chave)
  soma <- 0
  PARA cada letra de chave faça
    soma <- soma + codigo(letra)
  fim
  RETORNE soma mod 5
fim

escreva(hash("SOL"))

Quando a função atrapalha em vez de ajudar

Uma função hash mal escolhida transforma a estrutura veloz numa estrutura lenta, sem aviso. O sintoma é sempre o mesmo: chaves se acumulando em poucos baldes. Isso acontece quando a função ignora parte da chave (só a primeira letra), quando o tamanho do vetor combina mal com o padrão das chaves, ou quando a regra é fraca demais para embaralhar. No pior caso, se tudo cai no mesmo balde, a tabela hash se comporta como uma lista comum, e buscar volta a ser vasculhar item por item. Por isso, na prática, você raramente escreve a própria função hash: usa a que a linguagem oferece, testada e ajustada por especialistas. Saber o que uma boa função faz ajuda a entender por que a estrutura às vezes desacelera.

Teste rápido

Por que a distribuição uniforme é importante numa função hash?

Perguntas frequentes

O que quer dizer a função ser determinística?
Quer dizer que, dada a mesma chave, ela devolve sempre o mesmo índice, hoje e amanhã, na primeira e na milésima vez. Sem isso a tabela não funcionaria: você guardaria a Ana num escaninho e, ao buscar, a função poderia apontar outro. Determinismo é o que garante que guardar e buscar cheguem à mesma posição.
Existe uma função hash perfeita, que nunca amontoa?
Para um conjunto de chaves conhecido e fixo, existe algo chamado hash perfeito, que evita choques. Mas no dia a dia, com chaves que entram e saem o tempo todo, o objetivo é uma função boa o bastante, que distribua bem na média. Perfeição total não é o alvo; distribuição equilibrada e cálculo rápido são.
Por que somar os códigos das letras espalha melhor que olhar a primeira?
Porque usa a chave inteira. Se a função olha só a primeira letra, todos os nomes que começam com a mesma letra caem no mesmo balde, e há muitos. Somando todas as letras, chaves diferentes tendem a gerar somas diferentes, e o resto embaralha isso numa faixa de posições. Mais informação da chave, melhor o espalhamento.
Eu preciso escrever minha própria função hash?
Quase nunca. As linguagens já trazem funções hash boas e testadas para os tipos comuns, e é o que você usa ao criar um dicionário. Escrever a própria só faz sentido em casos especiais e exige cuidado, porque uma função fraca degrada tudo em silêncio. O valor de estudar isso é entender o que acontece por baixo.
O tamanho do vetor influencia o espalhamento?
Influencia. Quando o tamanho do vetor combina mal com o padrão das chaves, o resto pode concentrar valores em poucas posições. Por isso muitas implementações escolhem tamanhos que ajudam a espalhar, como números primos, e aumentam o vetor quando ele enche. O tamanho é uma peça do conjunto que mantém a distribuição equilibrada.
Função hash tem a ver com senhas e segurança?
O nome é o mesmo, mas o objetivo é outro. As funções hash de segurança (usadas para guardar senhas com proteção) são feitas para serem difíceis de reverter e são lentas de propósito. As funções hash de tabela são feitas para serem rápidas e espalhar bem. Aqui estamos falando das de tabela, voltadas para velocidade de busca.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.