Tabelas Hash-com Duplo Hashing

Embed Size (px)

Citation preview

  • Tabelas HashProf. Thales Castro

  • MotivaoDada uma tabela com uma chave e vrios valores por linha, quero rapidamente procurar, inserir e apagar registros baseados nas suas chaves Estruturas de busca sequencial/binria levam tempo at encontrar o elemento desejado.Ex: Arrays e listasEx: rvores5261784952614826419

  • MotivaoEm algumas aplicaes, necessrio obter o valor com poucas comparaes, logo, preciso saber a posio em que o elemento se encontra, sem precisar varrer todas as chaves.A estrutura com tal propriedade chamada de tabela hash.64112070123456720 ?20 mod 8 = 42045 ?45 mod 8 = 511 ?11 mod 8 = 311

  • Funes HashingOs registros com as chaves so armazenados nessa tabela, e endereados a partir de uma funo de transformao sobre a chave de pesquisaA essa funo d-se o nome de Funo HASHINGSeja M o tamanho da tabela:A funo de hashing mapeia as chaves de entrada em inteiros dentro do intervalo [1..M]Formalmente:A funo de hashing h(kj) [1,M] recebe uma chave kj {k0,..,km} e retorna um nmero i, que o ndice do subconjunto mi [1,M] onde o elemento que possui essa chave vai ser manipulado

  • Funes HashingMtodo pelo qual:As chaves de pesquisa so transformadas em endereos para a tabela (funo de transformao);Obtm-se valor do endereo da chave na tabela HASHTal funo deve ser fcil de se computar e fazer uma distribuio equiprovvel das chaves na tabelaExistem vrias funes Hashing, dentre as quais:Resto da DivisoMeio do QuadradoMtodo da DobraMtodo da MultiplicaoHashing Universal

  • Resto da DivisoForma mais simples e mais utilizada Nesse tipo de funo, a chave interpretada como um valor numrico que dividido por um valorO endereo de um elemento na tabela dado simplesmente pelo resto da diviso da sua chave por M (Fh(x) = x mod M), onde M o tamanho da tabela e x um inteiro correspondendo chave0
  • Resto da Diviso

    Ex: M=1001 e a seqncia de chaves: 1030, 839, 10054 e 2030Chave Endereo 1030 29 10054 53 839 838 2030 29

  • Resto da Diviso DesvantagensFuno extremamente dependente do valor de M escolhidoM deve ser um nmero primoValores recomendveis de M devem ser >20

  • Funes HashSeja qual for a funo, na prtica existem sinnimos chaves distintas que resultam em um mesmo valor de hashing. Quando duas ou mais chaves sinnimas so mapeadas para a mesma posio da tabela, diz-se que ocorre uma coliso.

  • Tratamento de ColisesAlgumas solues conhecidas

  • Tabelas Hash- ColisesQualquer que seja a funo de transformao, existe a possibilidade de colises, que devem ser resolvidas, mesmo que se obtenha uma distribuio de registros de forma uniforme;Tais colises devem ser corrigidas de alguma forma; O ideal seria uma funo HASH tal que, dada uma chave 1
  • Resto da Diviso - ColisoNo exemplo dado, M=1001 e a seqncia de chaves: 1030, 839, 10054 e 2031

    Chave Endereo 1030 29 10054 53 839 838 2030 29

  • Tratamento de ColisesAlguns dos algoritmos de Tratamento de Colises so:Endereamento FechadoEndereamento AbertoHashing LinearHashing Duplo

  • Endereamento FechadoTambm chamado de Overflow Progressivo EncadeadoAlgoritmo: usar uma lista encadeada para cada endereo da tabelaVantagem: s sinnimos so acessados em uma busca. Processo simples. Desvantagens: necessrio um campo extra para os ponteiros de ligao.Tratamento especial das chaves: as que esto com endereo base e as que esto encadeadas

  • Endereamento FechadoNo endereamento fechado, a posio de insero no muda. Todos devem ser inseridos na mesma posio, atravs de uma lista ligada em cada uma.0123420 mod 5 = 018 mod 5 = 325 mod 5 = 0 coliso com 20

  • Endereamento FechadoProgram TabelaHash;Const n = 50;Type Ponteiro = ^no;Type no = recorditem: integer;prox: Ponteiro;End;Var posicoes: array [1..n] of Integer;Procedure Inicia_Hash;Var i: integer;Beginfor i:=1 to n doposicoes[i] := nil;End;A tabela hash, neste caso, contm um array de listas ligadas

  • Endereamento FechadoQuando uma chave for inserida, a funo hash aplicada, e ela acrescentada lista adequadaProcedure inserir(chave: integer); Var i: integer; aux: ponteiro;Begin i := hashCode(chave); aux := lista[i]; if aux = nil then beginnew[lista[i]];lista[i] := chave;lista[i].^.prox := nil; end else begin while aux^.prox nil do aux := aux^.prox; new(aux^.prox); aux := aux^.prox; aux^.prox := nil; aux^.item := chave;End;End;

  • Endereamento FechadoA busca feita do mesmo modo: calcula-se o valor da funo hash para a chave, e a busca feita na lista correspondente.Se o tamanho das listas variar muito, a busca pode se tornar ineficiente, pois a busca nas listas se torna seqencial012320408832151160

  • Endereamento Fechado obrigao da funo HASH distribuir as chaves entre as posies de maneira uniforme001234561510314881320

  • Hashing LinearTambm conhecido como Overflow ProgressivoConsiste em procurar a prxima posio vazia depois do endereo-base da chaveVantagem: simplicidade Desvantagem: se ocorrerem muitas colises, pode ocorrer um clustering (agrupamento) de chaves em uma certa rea. Isso pode fazer com que sejam necessrios muitos acessos para recuperar um certo registro. O problema vai ser agravado se a densidade de ocupao para o arquivo for alta

  • Hashing Linear64112070123456727 ?27 mod 8 = 3112027

  • Hashing Linear - ImplementaoA tabela hash, neste caso, contm um array de objetos, e posies vazias so indicadas por -1. Neste caso, os objetos sero do tipo Integer:Program TabelaHash;Const n = 50;Var posicoes: array [1..n] of Integer;Procedure Inicia_Hash;Var i: integer;Beginfor i:=1 to n doposicoes[i] := -1;End;

  • Hashing Linear - ImplementaoNa insero, a funo hash calculada, e a posio incrementada, at que uma posio esteja livreProcedure inserir(chave: integer;) {Var i: integer;Begini := FuncaoHash(chave);while (posicoes[i] -1) i := (i + 1) mod n;posicoes[i] := chave;End;

  • Hashing LinearValores: 52, 78, 48, 61, 81, 120, 79, 121, 92 Funo: hash(k) = k mod 13 Tamanho da tabela: 13

  • Hashing DuploTambm chamado de re-hash Ao invs de incrementar a posio de 1, uma funo hash auxiliar utilizada para calcular o incremento. Esta funo tambm leva em conta o valor da chave. Vantagem: tende a espalhar melhor as chaves pelos endereos. Desvantagem: os endereos podem estar muito distantes um do outro (o princpio da localidade violado), provocando seekings adicionais

  • Hashing Duplo6411205370123456727 ?H(27) = 27 mod 8 = 31127Inc(27) = 27*4+7 = 115

  • Hashing Duplo - ImplementaoA estrutura semelhante ao Hashing Linear: um vetor de chavesProgram TabelaHash;Const n = 50;Var posicoes: array [1..n] of Integer;Procedure Inicia_Hash;Var i: integer;Beginfor i:=1 to n doposicoes[i] := -1;End;

  • Hashing Duplo - ImplementaoNa insero, a funo hash calculada. Caso exista conflito, chama-se uma funo hash alternativa at que uma posio esteja livreProcedure inserir(chave: integer);Var i: integer;Begini := FuncaoHash(chave);while (posicoes[i] -1) i := FunoHash_Alternativa(chave);posicoes[i] := chave;End;

  • Endereamento Aberto Remoo Para fazer uma busca com endereamento aberto, basta aplicar a funo hash, e a funo de incremento at que o elemento ou uma posio vazia sejam encontrados.Porm, quando um elemento removido, a posio vazia pode ser encontrada antes, mesmo que o elemento pertena a tabela:Insero do 27Remoo do 20Busca pelo 27

  • Endereamento Aberto: RemooPara contornar esta situao, mantemos um bit (ou um campo booleano) para indicar que um elemento foi removido daquela posio:27Esta posio estaria livre para uma nova insero, mas no seria tratada como vazia numa busca.

  • Tabelas HASH Dinmica

  • Endereamento Aberto ExpansoNa poltica de hashing, h que chamamos de fator de carga (load factor). Ele indica a porcentagem de clulas da tabela hash que esto ocupadas, incluindo as que foram removidas.Quando este fator fica muito alto (ex: excede 50%), as operaes na tabela passam a demorar mais, pois o nmero de colises aumenta.9 ?

  • Endereamento Aberto Expanso Quando isto ocorre, necessrio expandir o array que constitui a tabela, e reorganizar os elementos na nova tabela. Como podemos ver, o tamanho atual da tabela passa a ser um parmetro da funo hash.3440X1195Tamanho = 7

  • Endereamento Aberto Expanso O problema : Quando expandir a tabela? O momento de expandir a tabela pode variar Quando no for possvel inserir um elemento Quando metade da tabela estiver ocupada Quando o load factor atingir um valor escolhidoA terceira opo a mais comum, pois um meio termo entre as outras duas.

  • Quando no usar Hashing?Muitas colises diminuem muito o tempo de acesso e modificao de uma tabela hash. Para isso necessrio escolher bem:- a funo hash - o algoritmo de tratamento de colises - o tamanho da tabelaQuando no for possvel definir parmetros eficientes, pode ser melhor utilizar rvores balanceadas (como AVL), em vez de tabelas hash.

  • FIM