Tabelas de Dispersão (Hash Tables)



Objetivo

Buscas com Complexidade Média = O(1)

Função de Dispersão

Entrada: chave de busca
Saída: número inteiro no intervalo [0...m-1] (m é o tamanho de um vetor).
Endereço Base: número calculado pela função de dispersão.
Colisão: chaves diferentes com endereços base idênticos.
 

Método Direto

Problemas

m = maior_chave+1
int FuncDis(chave)

     return(chave); 
}

  • Total de espaços vazios pode ser muito grande.
       (Chaves: 1,4,789560)


 

Método da Divisão

Problemas

int FuncDis(chave,m)

     return(chave%m); 
}

  • Para certos valores de m e certo conjuntos de chaves, 
       o número de colisões pode ser muito elevado.

   Ex: m = 128 =2 e  chaves são datas na repres. abaixo

                      Dia   Mes    Ano
   8/4/67 -> 01000 0100 1000011 
                                       \   resto  /

   FuncDis(67/4/8,128) = 67
   FuncDis(67/12/3,128) = 67

   !!! Todas as datas de um mesmo ano receberão o
        mesmo índice !!!
 


 

Método da Dobra

Execução

t = Tamanho da Dobra 
d = Total de 'dígitos' da chave 

int FuncDis(char * chave, int t, int d)
{
     temp = chave  // strcpy 
     for( i = 0 ; i < (d/t)-1 ; ++i )
     {
        for( j = 0 ; j < t ; ++j )
        { 
           temp[i*t+j+t] = 
               soma(temp[i*t+j+t],temp[(i*t+j+t)-(2j+1)]);
        }
     }
     return(converte(temp[i*t ... i*t+t-1])); 
}

char soma(char i, char j) // Soma ignorando vai-um
converte() // Transforma 'string' em inteiro.


Chave: 279384
t = 2
d = 6
Método da Dobra:

  • Dobra 27 em 93 e soma 
            descartando 'vai-um'

  • 7 + 9 = 6 (16 descartando 1) , 2+3 = 5 

  • Resultado Intermediário: 6584

  • Dobra 65 em 84 e soma ...

  • 5+8 = 3, 6+4 = 0 

  • Resultado Final: 30
     

 

  FuncDis("279384",2,6) = 30;


 

Método da Análise dos Dígitos

Execução

Acesso prévio a todas as chaves (população conhecida):

Escolha, como endereço base, o valor do dígito
na posição que resulta na menor quantidade de colisões.

Acesso a uma amostra das chaves:

Métodos de estimativa estatística.

Chaves: 443 462 492 681 712 972

1os Digitos: { 4 4 4 6 7 9 } 
       -> 3 quatros, 1 seis, 1 sete e 1 nove.
2os Digitos: { 4 6 9 8 1 7 }
       -> 1 um, 1 quatro, ... (adivinha o resto :-)
3os Digitos: { 3 2 2 1 2 2 }
       -> 1 um, 4 dois,...

Escolhendo o segundo dígito como endereço 
base não teríamos nenhuma colisão em
uma tabela com 10 compartimentos [0..9]

Já com o terceiro, teríamos 3.

Tratamento de Colisões

Material de Apoio