Você está na página 1de 13

Estruturas de Dados

Hashing
Prof. Ricardo J. G. B. Campello
Parte deste material baseado em adaptaes e extenses de slides disponveis em http://ww3.datastructures.net (Goodrich & Tamassia).

Motivao
rvores AVL permitem realizar as operaes bsicas de busca, insero e remoo de itens em tempo O(log n), o n o no. de itens possvel conseguir desempenho melhor ???

Hashing
Uma abordagem para tentar obter desempenho superior quele das rvores AVL conhecida como hashing Essa abordagem utiliza uma estrutura de dados denominada tabela hash
Tambm denominada tabela de disperso

Tabela Hash
Uma tabela hash para um dado tipo de chave consiste de:
Uma funo hash h Um arranjo (tabela) de tamanho N

Uma funo hash h mapeia chaves de um dado tipo em inteiros em um intervalo fixo [0, N 1]
O valor inteiro h(k) [0, N 1] chamado de valor hash da chave k

Tabela Hash
Aplicao em Mapas / Dicionrios:
Item com chave k armazenado no ndice i = h(k) da tabela O ndice calculado, no procurado

Tabela Hash - Exemplo


Tabela hash para um mapa armazenando itens (CPF, Dados Pessoais), onde a chave CPF um inteiro positivo com 11 dgitos No exemplo ao lado utilizase um arranjo de tamanho N = 10.000 e a seguinte funo hash:
h(k) = 4 ltimos dgitos de k

0 1 2 3 4 9997 9998 9999

025.612.000-01 981.101.000-02

451.229.000-04

200.751.799-98

Pode haver conflitos...?

Colises
Colises ocorrem quando diferentes chaves so mapeadas sem distino na mesma clula da tabela Colises podem ocorrer tanto na fase de codificao das chaves (h1) como na fase de compresso (h2) Ocorrendo na fase de codificao, no h como serem revertidas na fase de compresso Colises requerem tratamentos a

0 1 2 3 4

612-0001

229-0004

101-0004

posteriori que, por sua vez,


demandam esforo computacional Funes hash devem ser simples e rpidas de calcular, minimizando ao mximo colises

Note que impossvel evitar completamente colises se o fator de carga (load factor) de uma tabela hash for >1 Esse fator definido como a razo entre o no. n de chaves pelo tamanho da tabela N: = n/N

Funes Hash
Uma funo hash composta das seguintes sub-funes: Cdigo Hash (hash code): h1: chaves inteiros Funo de Compresso: h2: inteiros [0, N 1] Usualmente, quando se assume que j se dispe de uma codificao inteira das chaves, refere-se funo de compresso sozinha como funo hash O cdigo hash (quando necessrio) aplicado primeiro; em seguida a funo de compresso aplicada ao resultado: h(k) = h2(h1(k)) A meta da funo hash dispersar as chaves de forma que essas ocupem a tabela da forma mais uniforme possvel

Cdigos Hash
Casting:
Interpretao dos bits da chave como um inteiro Por exemplo, para chaves numricas em ponto flutuante:
k = m*10e

Uma alternativa somar os inteiros correspondentes mantissa e o expoente do nmero em representao de ponto flutuante
h1(k) = m + e

Cdigos Hash
Soma de Componentes:
A idia de somar inteiros correspondentes a partes de uma representao pode ser estendida para qualquer chave k que possa ser representada por uma srie k0, k1, ..., km1 de inteiros Em outras palavras:

h1 (k ) = ki
i =0

m1

til em muitos casos, mas incapaz de distinguir chaves distintas que diferem entre si apenas pela ordem das componentes ki Esse o caso de chaves tipo string, representadas como sries de inteiros dados pelos cdigos ASCII de cada um dos seus caracteres (ou pela ordem alfabtica do caractere)

Cdigos Hash
Acumulao Polinomial:
Ao invs de uma soma simples, utiliza-se o seguinte polinmio: h1(k) = k0 + k1 a + k2 a2 + + km1am1 para um valor fixo de a Funciona bem, em especial para strings
p. ex. as escolhas empricas a = 33, 37, 39 ou 41 geram em torno de apenas 6 colises para 50.000 palavras em Ingls ! Muitas vezes basta tomar apenas um subconjunto dos m (p. ex. 10) primeiros / ltimos caracteres da string

Cdigos Hash
Acumulao Polinomial (Nota):
h1(k) = k0 + k1 a + k2 a2 + + km1am1 Esse polinmio pode ser avaliado em tempo O(m) utilizando a Regra de Horner:
Os seguintes polinmios so calculados recursivamente em tempo O(1): p0(k) = km1 pi (x) = kmi1 + api1(k) Tem-se h1(k) = pm1(k) i = 1, 2, , m 1

Funes de Compresso
Resto da Diviso:
h2(y) = | y | mod N Exemplo:
Cdigos hash: y = [200, 205, 210, 215, ..., 595, 600] Para N = 101, tem-se:
h2(y) = [99, 3, 8, 13, ..., 90, 95] pois os mltiplos de 101 so 101, 202, 303, 404, 505, ...

Note que no ocorre qualquer coliso nesse caso

Nota:
O mdulo |.| permite lidar com cdigos hash negativos... mas faz com que esses conflitem com suas contrapartidas positivas...

Funes de Compresso
Resto da Diviso (cont.):
O tamanho N da tabela usualmente escolhido primo
A razo formal est relacionada com a teoria dos nmeros Informalmente, tem-se que padres do tipo y = pN+q para q inteiro positivo e p = 0,1,2,... so menos comuns em cdigos hash para N primo Note que qualquer cdigo hash seguindo este padro possui o mesmo valor h2(y) !

Exemplo: y = [200, 205, 210, 215, ..., 595, 600]


Para N = 101, j vimos que no ocorre qualquer coliso J para N = 100, cada cdigo ter o mesmo valor hash de ao menos outros 3 cdigos !

Funes de Compresso
Resto da Diviso (cont.):
Heurstica:
Estimar a quantidade de chaves n e definir N como o no. primo que mais aproxima o fator de carga = n/N desejado

Exemplo:
n = 2000 chaves e fator de carga desejado = 3 escolhe-se N = 701 como no. primo mais prximo de 2000/3

Funes de Compresso
Existem outras funes de compresso:
Multiplicao-Diviso Multiply, Add and Divide (MAD) Funes Universais

De formas distintas, essas funes buscam reduzir a sensibilidade escolha de N e/ou minimizar a probabilidade de colises.

Tratamento de Colises
Colises ocorrem quando dois itens so mapeados na mesma clula da tabela Um mtodo simples e eficiente de lidar com colises que no podem ser evitadas conhecido como encadeamento externo
ou separate chaining

0 1 2 3 4

025-612-0001


451-229-0004 981-101-0004

Nesse mtodo, cada clula da tabela aponta (ponteiro) para uma lista dos itens mapeados naquela clula O tempo adicional para percorrer essas listas e o espao extra para armazen-las so as razes pelas quais colises devem ser evitadas ao mximo

Rehashing: Em aplicaes
dinmicas, quando o nmero de colises aumenta muito em funo do fator = n/N, pode-se criar uma nova tabela e re-dispersar as chaves

Performance
Hiptese:
funo hash eficiente, que distribua de maneira uniforme as chaves, ou seja, distribuio de probabilidade de atribuio de chaves uniforme sobre o conjunto de clulas da tabela

O tamanho mdio (esperado) das listas para separate chaining O(n/N) Logo, fazendo o tamanho da tabela ser proporcional ao nmero de chaves, ou seja, N O(n), faz-se o tamanho mdio das listas para separate chaining ser O(1)
Pode-se fazer isso estimando de antemo o no. tpico de chaves que estaro usualmente armazenadas na tabela ou via rehashing ...

Performance (cont.)
Nesse caso, todas as operaes (busca, insero e remoo) executam na mdia em tempo constante assumindo que a funo hash e as operaes de remoo e insero nas listas tambm executam em tempo cte. No pior caso, quando todas as chaves so mapeadas em uma mesma clula, recai-se essencialmente na implementao baseada em lista, com busca e remoo em O(n)
Porque insero O(1) mesmo nesse pior caso... ?

Comparao com AVL


Busca Tabela Hash O(1)
esperado

Insero Remoo Notas O(1) O(1)


esperado O(n) no pior caso para busca e remoo implementao simples implementao complexa

rvores O(log n) pior caso AVL

O(log n)
pior caso

O(log n)
pior caso

10

Variantes e Casos Particulares


Endereamento aberto: Denominada open addressing em ingls, uma estratgia de tratamento de colises na qual um item em coliso alocado a uma outra clula disponvel da tabela Trata-se de uma abordagem voltada a aplicaes onde se tem restries severas de memria, que podem ser minimizadas ao preo de um maior esforo de processamento A idia , em caso de conflito ao tentar inserir um novo item, percorrer (sondar) a tabela buscando por uma clula no ocupada
Diferentes estratgias de sondagem:
linear, quadrtica, hashing duplo...

Estratgias especficas tambm para busca e remoo de elementos

O fator de carga nunca pode exceder 1 pois cada clula da tabela armazena um nico item

Variantes e Casos Particulares


Endereamento direto:
Denominado direct addressing em ingls, trata-se de um caso muito particular de hashing onde as chaves so naturalmente inteiros em {0, 1,..., N1} Nesse caso, a funo hash dispensvel, no h colises se chaves forem nicas e todas as operaes so O(1) O problema que, como no se pode reduzir N pois os valores das chaves esto naturalmente entre 0 e N1, perde-se o controle sobre o fator de carga
Nesse caso, se o no. de chaves tal que n << N, o endereamento direto implica uma perda de espao pela alocao de uma tabela de tamanho muito superior ao necessrio

11

Variantes e Casos Particulares


Hashing Perfeito:
Em aplicaes muito particulares onde o conjunto de chaves esttico e conhecido a priori, pode-se projetar um hashing perfeito
por exemplo, conjunto de palavras reservadas de uma linguagem de programao (aplicao em compiladores)

Esse tipo de hashing executa todas as operaes de busca, insero e remoo em tempo O(1) no Pior Caso

Exerccios Sugeridos

Captulo 8 (Goodrich & Tamassia, 2002) Captulo 8 (Szwarcfiter & Markenzon, 1994) Captulo 5 (Ziviani, 2004)

24

12

Bibliografia
M. T. Goodrich & R. Tamassia, Data Structures and Algorithms in C++/Java, John Wiley & Sons, 2002/2005 M. T. Goodrich & R. Tamassia, Estruturas de Dados e Algoritmos em Java, Bookman, 2002 J. L. Szwarcfiter & L. Markenzon, Estruturas de Dados e seus

Algoritmos, LTC, 1994


N. Ziviani, Projeto de Algoritmos, Thomson, 2a. Edio, 2004 T. H. Cormen et al., Introduction to Algorithms, MIT Press, 2nd Edition, 2001

25

13

Você também pode gostar