You are on page 1of 7

9.1 Recapitulao At agora vimos basicamente dois tipos de estruturas de dados para o armazenamento flexvel de dados: Listas e rvores.

Cada um desses grupos possui muitas variantes. As Listas so simples de se implementar, mas, com um tempo mdio de acesso T = n/2, so impraticveis para grandes quantidades de dados. Em uma lista com 100.000 dados, para recuperar 3 elementos em seqncia faremos um nmero esperado de 150.000 acessos a nodos. Listas so timas porm, para pequenas quantidades de dados. As rvores so estruturas mais complexas, mas que possuem um tempo mdio de acesso T= logGn, onde G = grau da rvore. A organizao de uma rvore depende da ordem de entrada dos dados. Para evitar a deteriorao, h modelos de rvores que se reorganizam sozinhas. As principais so AVL e rvore B. 9.2 Hashing: Viso Geral uma forma extremamente simples, fcil de se implementar e intuitiva de se organizar grandes quantidades de dados. Permite armazenar e encontrar rapidamente dados por chave. Possui como idia central a diviso de um universo de dados a ser organizado em subconjuntos mais gerenciveis Possui dois conceitos centrais: Tabela de Hashing:Estrutura que permite o acesso aos subconjuntos. Funo de Hashing: Funo que realiza um mapeamento entre valores de chaves e entradas na tabela. Possui uma srie de limitaes em relao s rvores: No permite recuperar/imprimir todos os elementos em ordem de chave nem tampouco outras operaes que exijam seqncia dos dados. No permite operaes do tipo recuperar o elemento com a maior ou a menor chave. 9.2.1 Hashing: Introduo Idia geral: Se eu possuo um universo de dados classificveis por chave, posso: Criar um critrio simples para dividir este universo em subconjuntos com base em alguma qualidade do domnio das chaves. Saber em qual subconjunto procurar e colocar uma chave. Gerenciar estes subconjuntos bem menores por algum mtodo simples. Para isso eu preciso: Saber quantos subconjuntos eu quero e criar uma regra de clculo que me diga, dada uma chave, em qual subconjunto devo procurar pelos dados com esta chave ou colocar este dado, caso seja um novo elemento. Isto chamado de funo de hashing. Possuir um ndice que me permita encontrar o incio do subconjunto certo, depois de calcular o hashing. Isto a tabela de hashing. Possuir uma ou um conjunto de estruturas de dados para os subconjuntos. Existem duas filosofias: hashing fechado ou deendereamento aberto ou o hashing aberto ouencadeado. 9.2.1.1. Exemplo

9.2.1.2 Nomenclatura n: Tamanho do universo de dados. b: Nmero de subconjuntos em que dividimos os dados: depsitos. s: Capacidade de cada depsito (quando for limitada. Aplica-se somente a hashing fechado ou endereamento aberto). T: Cardinalidade do domnio das chaves. Quantas chaves podem existir ? n/T: Densidade identificadora. a = n/(b.s): Densidade de carga. b.s fornece a capacidade mxima (quando existir explcitamente). n/(b.s) indica o fator de preenchimento. Aplica-se somente a hashing fechado (endereamento aberto). 9.3 Hashing Aberto ou de Encadeamento Separado (Separate Chaining Hashing) Forma mais intuitiva de se implementar o conceito de Hashing. Intuitiva para ns, que usamos linguagens que lidam com ponteiros e estamos acostumados com a idia. Na poca do COBOL, era o modo menos comum. Utiliza a idia de termos uma tabela com b entradas, cada uma como cabea de lista para uma lista representando o conjunto bi. Calculamos a partir da chave qual entrada da tabela a cabea da lista que queremos. Utilizamos uma tcnica qualquer para pesquisa dentro de Podemos utilizar qualquer outra coisa para representar os rvore poderia ser uma opo. 9.3.1Hashing Aberto ou de Encadeamento Separado Implementao com a Tabela como Vetor bi. bi. Uma Tipicamente ser a tcnica de pesquisa seqencial em lista encadeada.

9.3.2 Hashing Aberto ou de Encadeamento Separado Implementao como Multilista

9.4 Hashing Fechado ou de Endereamento Aberto (Open Addressing Hashing) Utiliza somente uma estrutura de dados de tamanho fixo para implementar o hashing. No necessita de ponteiros para a sua implementao. Forma muito utilizada "antigamente". Adequada para implementao em disco (ISAM). Somente uma tabela dividida em partes iguais. reas de tamanho fixo para cada bi : Repositrios.

Cada repositrio examinado seqencialmente na busca por uma chave Quando um repositrio est cheio, h Filosofias para tratamento de estouros Utilizao do primeiro espao vazio Busca quadrtica Implementao com busca seqencial aps estouro. Suponha h(k) como mod(k, 10) estouro.

Manipulao de estouro: Usamos o primeiro espao livre. No caso do 60, isto foi logo apos duas entradas em "1".

No caso dos valores com chave apontando para "3", foram includos dois valores antes mesmo de ser includo algo com chave "hasheada" para "4". Critrio de parada de busca: Consideramos o arquivo inteiro como uma lista circular e paramos ao chegar de novo ao ponto de partida. Somente a consideramos uma chave como no existente. 9.5 Complexidade A ordem de complexidade de tempo de uma implementao de hashing linear O(n) e T(n) compe-se de trs termos: 1. O tempo para calcular a funo de hashing 2. O tempo para encontrar o incio do depsito indicado pela funo de hashing atravs da tabela de hashing 3. O tempo para encontrar a chave procurada dentro do seu depsito.

Estas complexidades so diferentes para as duas filosofias de implementao de hashing: aberto ou fechado. T(n) vai tender a ser algo em torno de n/b no caso ideal. Variam muito nos casos menos ideais. 9.6 Vantagens Simplicidade muito fcil de imaginar um algoritmo para implementar hashing. Escalabilidade Podemos adequar o tamanho da tabela de hashing ao nossa aplicao. Eficincia para n grandes n esperado em

Para trabalharmos com problemas envolvendo n = 1.000.000 de dados, podemos imaginar uma tabela de hashing com 2.000 entradas, onde temos uma diviso do espao de busca da ordem de n/2.000 de imediato. Aplicao imediata a arquivos Os mtodos de hashing, tanto de endereamento aberto como fechado, podem ser utilizados praticamente sem nenhuma alterao em um ambiente de dados persistentes utilizando arquivos em disco. 9.7 Desvantagens Dependncia da escolha de funo de hashing Para que o tempo de acesso mdio ideal T(n) = c1 . (1/b).n + c2 seja mantido, necessrio que a funo de hashing divida o universo dos dados de entrada em bconjuntos de tamanho aproximadamente igual. Tempo mdio de acesso timo somente em uma faixa A complexidade linear implica em um crescimento mais rpido em relao a n do que as rvores, p.ex. Existe uma faixa de valores de muito melhor do que uma rvore. Fora dessa faixa pior. 9.8 Funo de Hashing Possui o objetivo de transformar o valor de chave de um elemento de dados em uma posio para este elemento em um dos b subconjuntos definidos. um mapeamento de K -> {1,..,b}, onde K = K = {k0,..,km} em b o conjunto subconjuntos de de todos os valores de chave possveis no universo de dados em questo. Deve dividir o universo de chaves mesmo tamanho. {k0,..,km} n, determinada por b, onde o hashing ser

A probabilidade de uma chave em um dos subconjuntos bi:

kj pertencente a K aleatria qualquer cair i pertencente a [1,b] deve ser uniforme. K uniformemente entre os bi, a tabela

Se a funo de Hashing no dividir de hashing pode degenerar.

O pior caso de degenerao aquele onde todas as chaves caem em um nico conjunto bi. A funo "primeira letra" do exemplo anterior um exemplo de uma funo ruim. A letra do alfabeto com a qual um nome inicia no distribuda uniformememente. Quantos nomes comeam com "X" ? 9.8.1 Funes de Hashing Para garantir a distribuio uniforme de um universo de chaves entre conjuntos, foram desenvolvidas 4 tcnicas principais. kj bi : Lembre-se: a funo de hashing {k0,..,km} i [1,b] e devolve um nmero h(kj) -> [1,b] toma uma chave i, que o ndice do subconjunto b

onde o elemento possuidor dessa chave vai ser colocado.

As funes de hashing abordadas adiante supem sempre uma chave simples, um nico dado, seja string ou nmero, sobre o qual ser efetuado o clculo. Hashing sobre mais de uma chave, p.ex. "Nome" E "CPF" tambm possvel, mas implica em funes mais complexas. Principais Funes de Hashing: 9.8.1.1 Diviso Forma mais simples e mais utilizada para funo de hashing O endereo de um elemento na tabela de hashing dado simplesmente pelo resto da diviso da sua chave por b: h(kj) = mod(kj,b) + 1. O termo "+ 1" para numerao de domnio K. bi: i kj [1,b] a partir de 1. Diviso Meio do Quadrado Folding ou Desdobramento Anlise de Dgitos

Funciona se a distribuio de valores de chave

for uniforme em seu

Se as chaves, mesmo sendo numricas, possuem uma regra de formao que faz com que estejam irregularmente distribudas em seu domnio, o resto da diviso tambm no gera distribuio uniforme. Ex.: CPF. Uma ajuda sugerida a utilizao somente de nmeros primos de valores altos (acima de 20) como valores para b. Para chaves alfanumricas pode-se utilizar a soma de todos os valores numricos dos caracteres da chave como base. Antigamente utilizava-se simplesmente a representao binria do string como "numero". ruim porque para valores de b pequenos, toda a parte "mais alta" do string ignorada. Exemplo: Suponha b=1000 e a sequinte seqncia de chaves [Villas et.al.]: 1.030, 839, 10.054 e 2030. Teremos a seguinte distribuio: Chave Endereo 1030 30 10054 54 839 839 2030 30

Observe que 1030 e 2030 geram o mesmo endereo. A isto chama-se coliso. 9.8.1.2 Meio do Quadrado Calculada em dois passos: Eleva-se a chave ao quadrado Utiliza-se um determinado nmero de dgitos ou bits do meio do resultado. Idia geral: A parte central de um nmero elevado ao quadrado depende dele como um todo. Quando utilizamos diretamente bits: bits do meio do quadrado, podemos utilizar o seu valor para acessar diretamente uma tabela de 2rentradas. 9.8.1.3 Folding ou Desdobramento Mtodo para cadeias de caracteres Inspirado na idia de se ter uma tira de papel e de se dobrar essa tira formando um "bolinho" ou "sanfona". Baseia-se em uma representao numrica de uma cadeia de caracteres. Pode ser binria ou ASCII. Shift Folding e Dois tipos: Limit Folding. Folding: Shift Folding Divido um string em pedaos, onde cada pedao representado numericamente e somo as partes. Exemplo mais simples: somar o valor ASCII de todos os caracteres. O resultado uso diretamente ou como chave para uma Exemplo: Suponha que os valores ASCII de um string sejam os seguintes: 123, 203, 241, 112 e 20 O folding ser: 123 203 241 112 20 699 Folding: Limit Folding Uso a idia da tira de papel como sanfona: h(k) Se utilizarmos r

Exemplo mais simples: somar o valor ASCII de todos os caracteres, invertendo os dgitos a cada segundo caracter. Exemplo: Suponha que os valores ASCII de um string sejam os seguintes: 123, 203, 241, 112 e 20 O folding ser: 123 302 241 211

20 897 9.8.1.4 Anlise de Dgitos Pode ser utilizado quando eu conheo as distribuies dos dgitos ou caracteres das chaves til quando temos um domnio com poucas chaves ou com chaves com regra de formao bem conhecida. Escolhemos uma parte da chave para clculo do Hashing Esta parte dever ter uma distribuio conhecida Esta distribuio dever ser a mais uniforme possvel. Exemplo: Sabemos que o DDD e os 3 primeiros dgitos de um nmero telefnico no so distribudos de forma uniforme: no servem Diferentes estados possuem nmero diferente de telefones e a maioria das cidades comea seus nmeros com X22. Podemos supor que os 4 ltimos dgitos de um nmero telefnico so distribudos mais ou menos uniformemente: boa opo.