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.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: A função hash: espalhar bem as chaves.
Os objetivos desta aula. 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.
Veja o essencial, parte por parte.
O que faz uma função hash ser boa. Uma boa função hash é determinística: a mesma chave dá sempre o mesmo índice.
Por dentro de uma função simples. Dá para sentir a diferença com um exemplo.
Quando a função atrapalha em vez de ajudar. Usa só parte da chave (a primeira letra, por exemplo), ignorando o resto.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
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.
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")) // 4A 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.