Camada Zero · 03 · Hashing & Hash Tables

O map[string]int do Go parece mágica: você joga uma chave e ele acha o valor na hora, O(1). Não é mágica, é uma função de hash que converte a chave num índice de bucket. Insere chaves aqui embaixo, olha as colisões aparecerem, e veja o que acontece com a busca quando os buckets enchem.
Load factor (itens / buckets)0.00
0Itens
0Buckets
0Maior cadeia
Comparações da busca
item na cadeia comparando achou bucket com colisão
OperaçãoMédioPior
BuscaO(1)O(n)
InserçãoO(1)*O(n)
RemoçãoO(1)O(n)
* amortizado: a inserção é O(1) na média mesmo contando o rehash O(n) que acontece de vez em quando. O pior caso O(n) é quando todas as chaves caem no mesmo bucket e a tabela vira uma lista encadeada.

Na prática (map do Go)

m := make(map[string]int)
m["cat"] = 1           // insere/atualiza, O(1) médio
v, ok := m["cat"]      // lookup, ok=false se não existe
delete(m, "cat")        // remove

Hash table com chaining (esqueleto)

type entry struct { key string; val int }
type table struct { buckets [][]entry }

func (t *table) hash(k string) int {
    h := 0
    for _, c := range k {
        h = h*31 + int(c)   // hash polinomial simples
    }
    if h < 0 { h = -h }
    return h % len(t.buckets)
}

func (t *table) insert(k string, v int) {
    i := t.hash(k)
    for j := range t.buckets[i] {    // percorre a cadeia do bucket
        if t.buckets[i][j].key == k {
            t.buckets[i][j].val = v; return
        }
    }
    t.buckets[i] = append(t.buckets[i], entry{k, v})
    // se load factor > 0.75: dobra buckets e reinsere tudo (rehash)
}

func (t *table) get(k string) (int, bool) {
    i := t.hash(k)
    for _, e := range t.buckets[i] {   // O(tamanho da cadeia)
        if e.key == k { return e.val, true }
    }
    return 0, false
}

🧠 Desafio — Hashing

Mexe na tabela aqui de cima antes de responder (baixa os buckets, enche de chaves, busca). As duas últimas são de reflexão: escreve a sua e só então revela o modelo.