Upload
truongquynh
View
212
Download
0
Embed Size (px)
Citation preview
Tabelas - conceitos
Operações usuaisCriaçãoDestruiçãoInserção de registroExclusão de registroAlteração de registrosConsulta de registros
Tabelas - conceitos
Ordenação pode ser feita fisicamenteMétodo mais intuitivo
Exemplo:
NÚMERO NOME DT-NASCIMENTO SALÁRIO
10130 José 19600725 2500
10850 Paulo 19521203 1200
12700 Marcos 19740303 2860
12800 Antônio 19780523 1950
... ... ... ...
Tabelas - conceitos
Ordenação pode ser feita fisicamenteMétodo mais intuitivo
A tabela pode também ser encadeadaUm marcador para o início da tabela e percurso
circular
NÚMERO NOME DT-NASCIMENTO SALÁRIO
82800 Amilton 19780523 1950
10130 José 19600725 2500
10850 Paulo 19521203 1200
12700 Marcos 19740303 2860
... ... ... ...
2início
Tabelas - conceitos
Ordenação pode ser feita utilizando o encadeamento com o fornecimento de um elo entre os registrosComo uma lista encadeada
NÚMERO Demais campos... Elo
25 7
12 6
71 5
56 3
93 0
17 1
42 4
2início
Tabelas - conceitos
Ordenação pode ser feita utilizando um Vetor Indireto de Ordenação (VIO)
Exemplo:
NÚMERO Demais campos...
25
12
71
56
93
17
42
VIO
2
6
1
7
4
3
5
Tabelas - conceitos
VIOCaso a tabela não possa ser totalmente
disponível em memória principal, é conveniente fazer a carga de todo o VIO ou elo para garantir um bom processo de recuperação da informação da tabela
É possível, e às vezes muito recomendado, ter a tabela ordenada por mais de uma chaveMatrícula Nome
Em muitos casos, também é interessante ordená-la utilizando chaves compostasData de nascimento + Nome
Pesquisa sequencial
ProcedimentoElementos pesquisados sucessivamenteComparação determina se o elemento foi
encontrado ou nãoExemplo: buscar 4 (Arrays e lista encadeada)Importância no número médio de
comparações
5 2 6 1 7 8 4 9
5 2 6 1 4
Pesquisa sequencial
Número médio de comparações
5 2 6 1 7 8 4 9
5 2 6 1 4
Tempo de busca: O(n)
Comparações: (n + 1) / 2
Comparações = 1 + 2 + 3 + .... n = n ((n+1)/2) = n + 1 n n 2
Busca sequencial
Pesquisa sequencial em vetor não ordenado
Necessário pesquisar em todo o vetorfor i := 1 to tamanho_vetor { if vetor[i] == chave then retorna chave}
5 2 6 1 7 8 4 9
5 2 6 1 4
Tempo de busca: O(n)
Comparações: (n + 1) / 2
Busca sequencial
Pesquisa sequencial em vetor ordenadoCaso encontre um número maior que o
buscado, pare.for i := 1 to tamanho_vetor { if vetor[i] > chave then return -1 elseif vetor[i] == chave then retorna chave}
1 2 4 5 6 7 8 9
1 2 4 5 6
Tempo de busca: O(n)
Comparações: (n + 1) / 2
Ainda assim...
Busca sequencial usando frequência
E se alguns valores foram mais acessados que outros?Neste caso, podemos ordenar pela frequência
de recuperação que uma chave possui. Ou seja, a cada busca de uma chave, aumentamos sua frequência e ordenamos pela frequência...
4 8 14 5 3 7 0 9
Tempo de busca: O(n)Ainda assim...
0,50 0,16 0,15 0,04 ...
4 14 8 5 3 7 0 90,48 0,20 0,14 0,03 ...
Busca sequencial usando frequência
Número de comparações usando frequênciaExemplo:
Entrada FRA
1 0,50
2 0,30
3 0,15
4 0,04
5 0,01
EE = 1*0,50 + 2*0,30 + 3*0,15 + 4*0,04 + 5*0,01 = 1,76
EE = 1*0,01+ 2*0,04 + 3*0,15 + 4*0,30 + 5*0,50 = 4,24
Número médio de endereços examinados para a localização de uma entrada, considerando-se que elas aparecem nessa seqüência dentro da tabela:
Se as entradas estivessem distribuídas na ordem inversa (o caso mais desfavorável), o número médio de endereços examinados seria:
Busca sequencial usando frequência
Necessidade de conhecer previamente a frequência ou calculá-la utilizando um histórico de buscas bem-sucedidas
Auto-organização (numa abordagem mais simples):Armazenar o número de buscas, ao invés da
frequênciaAlterar a posição das chaves dado o número de
acessos em cada chave
4 8 14 5 3 7 0 950 42 23 ...
4 14 8 5 3 7 0 950 43 43 23 ...
43
Abordagem diferenteCalcular a posição da chave na tabela baseado no
valor da chave
Posição na tabela pode ser acessada diretamenteNão há necessidade de testesComplexidade é reduzida para O(1)
Busca sequencial: complexidade é O(n)Busca binária: complexidade é O(lg n)
Chave1
Chave2
Chave3
Chave4
Chave5
....
Chaven
h(chave) = posição
HashingSegundo o Webster's New World Dictionary, significa:
Fazer picadinho de carne e vegetais para cozinhar;Fazer uma bagunça
Qualquer que seja a função de transformação, colisões irão acontecer
O Paradoxo do aniversário (Feller, 1968, p.33) diz que em um grupo de 23 pessoas juntas ao acaso, existe uma chance maior do que 50% de que 2 pessoas comemorem aniversário no mesmo dia.
Assim, se for utilizada uma função de transformação uniforme que enderece 23 chaves randômicas em uma tabela de tamanho 365, a probabilidade de que haja colisões é maior do que 50%.
Paradoxo do aniversárioA probabilidade p de se inserir N itens consecutivos
sem colisão em uma tabela de tamanho M é:
Paradoxo do aniversárioAlguns valores de p para diferentes valores de N,onde
M=365.
Para N pequeno a probabilidade p pode ser aproximada por p ≈ N*(N −1) / 730. Por exemplo, para N=10 então p ≈ 87,7%.
HashingA função h deve ser tal que
Transforma uma chave em um índice na tabelaChave pode ser: cadeia de caracteres, um número, um
registro ... Função h é chamada de função hashing ou de
escrutínio.Universo de chaves mapeado em posições
Hashing A função h deve ser tal que
Transforma uma chave em um índice na tabela Chave pode ser: cadeia de caracteres, um número, um
registro ... Função h é chamada de função hashing ou de escrutínio. Universo de chaves mapeado em posições Colisões podem ocorrer:
HashingFunção de hashing perfeita
Transforma diferentes chaves em diferentes posições sem colisões
Para criar função perfeitaTabela tem que conter mesmo número de
posições que o número de elementos que sofreram hashing
Quais são os problemas?Pode-se não conhecer a priori o número total de
elementosO número possível de elementos pode ser muito maior
do que o número total de elementos
HashingExemplo: Armazenamento dos empregados de
uma empresa em um arrayQuantas posições o array terá que ter?Considerando que o número máximo de
funcionários possíveis é igual à quantidade de CPFs diferentes que podem existir. Quantas posições o array terá que ter?
HashingExemplo: Empregados identificados por CPF
Class Empregado{int cpf;char nome[80];char end[120];
...}
CPF como índice: 1 bilhão de entradas 000 000 000 a 999 999 999emp vet[1000000000]
Reservar espaço para o total de possíveis empregadosMas, se empresa possui apenas 500 empregados,
temos desperdício enorme de memória.
DivisãoCompressão de chaves alfanuméricasMultiplicaçãoEnlaçamento
Deslocado Limite
Função Meio-QuadradoExtraçãoTransformação da Raiz
Funções Hashing
Hashing - DivisãoManeira mais simplesUsar módulo da divisãoTSize = sizeof(table)h(k) = k mod TSize, caso k seja um númeroMelhor se Tsize é um número primo
Números primos tendem a distribuir os restos das divisões de maneira mais uniforme do que números não primos.
Se TSize não é um número primo pode-se utilizar função:h(k) = (k mod p) mod TSize, onde p é um número primo
maior que TSize
Divisores não primos podem trabalhar bem com a condição que não tenham fatores não primos maiores do que 20 (Lum et al., 1971).
Hashing – Compressão de chaves alfanuméricas
Utilizado quando as chaves são alfanuméricasChaves são representadas utilizando sua
representação interna
Muitas vezes surge a necessidade de comprimir uma chave, dado sua representação numérica excessivamente grandeUma idéia útil é utilizar o operador XOR (ou exclusivo)
B R A S I L
C2 D2 C1 D3 C9 CC
11000010 11010010 11000001 11010011 11001001 11001100
Representação hexadecimal e binária do código ASCII
Hashing – Compressão de chaves alfanuméricas
Utilização do XOR
Comprimindo a chave BRASIL para um total de 16 bits:
O cálculo final do endereço é feito a partir do valor comprimido, por exemplo, utilizando uma tabela com 521 entradas:
A B A xor B
0 0 0
0 1 1
1 0 1
1 1 0
(BR) 1100001011010010(AS) 1100000111010011(IL) 1100100111001100xor 1100101011001101 = 51917(10)
(51917 mod 521) + 1 = 338
Hashing – Compressão de chaves alfanuméricas
Problema do método:Chaves com permutações de grupos de
letras/dígitos irão produzir colisões.BRASIL, BRILAS, ASBRIL, ILBRAS irão produzir o
mesmo endereçoUma forma de contornar esse problema é
executar uma operação de rotação de bits de cada grupoRotação de 1 bit no segundo grupoRotação de 2 bits no terceiro grupo...
Hashing - MultiplicaçãoEste método utiliza uma propriedade do número
conhecido como inverso da relação áurea (ø-1), cujo valor é:
Se calcularmos K= , 1<= i<= 20:
i k i k1 6 11 72 2 12 43 8 13 04 4 14 65 0 15 26 7 16 87 3 17 58 9 18 19 5 19 710 1 20 3
Há permutação perfeita nas 10 primeiras posições
Quase acontece o mesmo nas demais posições!
Hashing - MultiplicaçãoPodemos generalizar, como função de endereçamento,
o valor
Considerando m o tamanho da tabela e i o valor da chave.
A função produzirá endereços no intervalo [0, m-1]Problema:
Computação lenta para cálculo da chaveDonald Knuth apresentou uma solução alternativa e
igualmente satisfatória
Hashing - MultiplicaçãoSegundo Donald Knuth [1973], ao invés de utilizar ø-1,
ele propõe que seja usado um valor onde w equivale ao tamanho da palavra do computador e A um inteiro tal que A e w sejam primos entre si.Por exemplo, considerando A = 19 e um computador
de 32 bits, temos:
O método deve ser aplicado em tabelas com 2k espaços
Nesse exemplo, o cálculo do endereço “e” no qual deve ser instalada a chave de valor C numa tabela de 2k registros é feito pela execução da seguinte seqüência de comandos:
e := C * A/we := e mod tamanho_tabela
Hashing - EnlaçamentoChave é dividida em diversas partesPartes são combinadas ou enlaçadas e
frequentemente transformadas para produzir endereço alvo
TiposEnlaçamento deslocadoEnlaçamento limite
Hashing – Enlaçamento deslocadoEnlaçamento deslocado
Chave é dividida em partesUma parte é colocada embaixo da outraChaves são processadas a seguir
Exemplo: código pessoal 123-45-6789Dividir em partes e colocar uma embaixo da outra
123456789
Processamento: adicionar partes
123+456+789 = 1368dividir em módulo TSize
Supondo TSize = 10001368 mod 1000 = 368
Hashing – Enlaçamento limiteEnlaçamento limite
Chave é dividida em partesCada parte predeterminada será colocada em ordem inversa
Exemplo: código pessoal 123-45-6789Dividir em partes e colocar uma embaixo da outra
123456789
Processamento, 456 é considerado na ordem inversaadicionar partes
123+654+789 = 1566dividir em módulo TSize
Supondo TSize = 10001566 mod 1000 = 566
Hashing – Função Meio-Quadrado
A chave é elevada ao quadrado e parte do resultado é usada como endereço.
Exemplo: chave 312131212 = 9740641Considerando TSize igual a 1000 e parte do meio para
endereçamentoh(3121) = 406
9740641
Uma máscara binária pode ser utilizada para obter posiçãoSe tamanho da tabela é 1024 (em binário 10000000000)31212 em binário é igual a 10010100101000010110000010101000010 , que é igual a 322, pode ser extraído usando
máscara e uma operação de deslocamento
ExtraçãoParte da chave é usada para calcular o endereçoExemplo:
Código 123-45-6789Pode-se utilizar
primeiros quatro dígitos: 1234Últimos quatro dígitos: 6789Dois primeiros dígitos combinados com os dois últimos: 1289...
Parte escolhida deve produzir boa distribuição das chavesParte descartada deve distinguir pouco as chavesExemplo:
Universidade onde os primeiros 3 dígitos iguais a 999 indica estudante estrangeiroEstes dígitos podem ser omitidos
Transformação da RaizMudar a base do número, por exemplo, de
base 10 para base nonal e dividir em módulo TSize
Exemplo:345 em decimal é igual a 423 em base nonalSe TSize igual a 100
h(345) = 23
Não evita colisões
onde é uniformemente randômico.
Hashing Universal Qualquer função de hash está sujeita ao problema de criar
chaves iguais para elementos distintos. Um estratégia para minimizar as colisões é escolher
aleatoriamente (em tempo de execução) uma função hash a partir do conjunto de funções cuidadosamente desenhado.
Para strings, por exemplo, podemos assumir Deitzfelbinger et al (1992) trata a string x como os
coeficientes de um polinômio módulo um primo. Em , seja um primo, definimos:
Resolução de colisõesColisões podem ocorrer
Mais de uma chave atribuída para a mesma posição
Exemplo: hashing que considera a primeira letra de cada nomeNomes que comecem com a mesma letra teriam conflitos
Função hashing e tamanho da tabela pode ajudar a diminuir o número de colisões
Resolução de colisões
Endereçamento abertoRe-hashingEncadeamento
SeparadoCoalescidoCoalescido com porão
Endereçamento em balde
Endereçamento AbertoUsar próxima posição vaziaInserimos chave u, x, v, w, y e z na tabela:
Inserir u e v h(u)=423 e h(x)=425.
Inserir v h(v)=423 (colisão com u h(u)=423)Próxima posição vazia é 424
Inserir w h(w)=423 (onde inserir w?)
Inserir y e z h(y)=h(z)=425
Endereçamento AbertoResultado da inserção de u, x, v, w, y e z
• Suponha que deseja-se procurar n, onde h(n)=424
• É necessário ir até o 429 para concluir que não n não está presente
• Remoção com endereçamento aberto também leva a inconsistência. Se x for removido, acessos a w, y e z estariam perdidos
• Em alguns casos, não há remoção quando se usa “hashing”
Re-hashingSe houver colisão, usar outra função para
encontrar próxima posição Exemplo: utilizar r(x) para resolver colisão
Posições para uma chave x são encontradas da seguinte forma:p1 = h(x)
p2 = h(x)+r(x),
p3 = h(x)+2*r(x)Etc
De forma mais geral:h(k, i) = (h
1(k) + ih
2(k)) mod m
Re-hashingConsidere a tabela abaixo com 13 espaçosConsidere incluir o valor 14 na tabela, com
h1(k) = k mod 13
h2(k) = 1+(k mod 11)
Em qual posição k=14 será inserida?
0
1 79
2
3
4 69
5 98
6
7 72
8
9
10
11 50
12
Re-hashingConsidere a tabela abaixo com 13 espaçosConsidere incluir o valor 14 na tabela, com
h1(k) = k mod 13
h2(k) = 1+(k mod 11)
Em qual posição k=14 será inserida?posição 9!
0
1 79
2
3
4 69
5 98
6
7 72
8
9
10
11 50
12
Re-hashingVantagem de usar outra função r diferente de h:
se h(x)=h(y)=h(z)=i, é pouco provável que r(y)=r(z), logox fica em i;y fica em i+r(y); e z em i+2*r(z)
busca por z é mais rápida, pois evita calcular r(y) Identificação de que não está presente, quando
encontra-se posição vaziaTem problemas também para remoção
Encadeamento (separado)Cada posição da tabela está associada com uma lista ligadaExemplo:
Este método é chamado de encadeamento separadoNeste método a tabela nunca irá transbordarAumento do comprimento da lista pode degradar o
desempenho da recuperaçãoPode-se ordenar os registros presentes na lista ligada
Não será executada busca exaustivaNecessidade de espaço adicional para os ponteiros
Encadeamento (coalescido) Cada posição na tabela possui espaço para a chave (ou info) e para um
ponteiro que aponta para a posição da próxima chave Método quando ocorre colisão
Encontrar primeira posição disponível Armazenar índice dessa posição com a chave que já está na tabela da
lista ligada Exemplo:
Inserir A2, A3, A5 0
1
2 A2
3 A3
4
5 A5
6
7
8
9
Encadeamento (coalescido) Cada posição na tabela possui espaço para a chave (ou info) e para um
ponteiro que aponta para a posição da próxima chave Método quando ocorre colisão
Encontrar primeira posição disponível Armazenar índice dessa posição com a chave que já está na tabela da
lista ligada Exemplo:
Inserir A2, A3, A5
Inserir B5
Colisão com A5
0
1
2 A2
3 A3
4
5 A5
6
7
8
9
Encadeamento (coalescido) Cada posição na tabela possui espaço para a chave (ou info) e para um
ponteiro que aponta para a posição da próxima chave Método quando ocorre colisão
Encontrar primeira posição disponível Armazenar índice dessa posição com a chave que já está na tabela da
lista ligada Exemplo:
Inserir A2, A3, A5
Inserir B5
Colisão com A5
Inserir B5 na posição vazia a partir do final da tabela
0
1
2 A2
3 A3
4
5 A5 9
6
7
8
9 B5
Encadeamento (coalescido) Cada posição na tabela possui espaço para a chave (ou info) e para um
ponteiro que aponta para a posição da próxima chave Método quando ocorre colisão
Encontrar primeira posição disponível Armazenar índice dessa posição com a chave que já está na tabela da
lista ligada Exemplo:
Inserir A2, A3, A5
Inserir B5
Colisão com A5
Inserir B5 na posição vazia a partir do final da tabela
Inserir A9 (Colisão com B5)
0
1
2 A2
3 A3
4
5 A5 9
6
7
8
9 B5
Encadeamento (coalescido) Cada posição na tabela possui espaço para a chave (ou info) e para um
ponteiro que aponta para a posição da próxima chave Método quando ocorre colisão
Encontrar primeira posição disponível Armazenar índice dessa posição com a chave que já está na tabela da
lista ligada Exemplo:
Inserir A2, A3, A5
Inserir B5
Colisão com A5
Inserir B5 na posição vazia a partir do final da tabela
Inserir A9 (Colisão com B5) Inserir na próxima posição vazia e apontar
0
1
2 A2
3 A3
4
5 A5 9
6
7
8 A9
9 B5 8
Encadeamento (coalescido) Cada posição na tabela possui espaço para a chave (ou info) e para um
ponteiro que aponta para a posição da próxima chave Método quando ocorre colisão
Encontrar primeira posição disponível Armazenar índice dessa posição com a chave que já está na tabela da
lista ligada Exemplo:
Inserir A2, A3, A5
Inserir B5
Colisão com A5
Inserir B5 na posição vazia a partir do final da tabela
Inserir A9 (Colisão com B5) Inserir na próxima posição vazia e apontar Inserir B2 (Colisão com A2)
0
1
2 A2
3 A3
4
5 A5 9
6
7
8 A9
9 B5 8
Encadeamento (coalescido) Cada posição na tabela possui espaço para a chave (ou info) e para um
ponteiro que aponta para a posição da próxima chave Método quando ocorre colisão
Encontrar primeira posição disponível Armazenar índice dessa posição com a chave que já está na tabela da
lista ligada Exemplo:
Inserir A2, A3, A5
Inserir B5
Colisão com A5
Inserir B5 na posição vazia a partir do final da tabela
Inserir A9 (Colisão com B5) Inserir na próxima posição vazia e apontar Inserir B2 (Colisão com A2) Inserir na próxima posição vazia e apontar
0
1
2 A2 6
3 A3
4
5 A5 9
6 B2
7
8 A9
9 B5 8
Encadeamento (coalescido)Posições disponíveis podem ser marcadas, por
exemplo, -2 em next-1 pode ser usado para indicar o final de uma
cadeia0 -2
1 -2
2 A2 6
3 A3 -1
4 -2
5 A5 9
6 B2 -1
7 -2
8 A9 -1
9 B5 8
Encadeamento (coalescido)Posições disponíveis podem ser marcadas, por
exemplo, -2 em next-1 pode ser usado para indicar o final de uma
cadeiaExemplo:
Inserir A7
Inserir C2
Colisão com A2
Segue-se para posição 6Posição 6 está ocupada Next indica fim da cadeia (-1)
0 -2
1 -2
2 A2 6
3 A3 -1
4 -2
5 A5 9
6 B2 -1
7 A7 -1
8 A9 -1
9 B5 8
Encadeamento (coalescido)Posições disponíveis podem ser marcadas, por
exemplo, -2 em next-1 pode ser usado para indicar o final de uma
cadeiaExemplo:
Inserir A7
Inserir C2
Colisão com A2
Segue-se para posição 6Posição 6 está ocupada Next indica fim da cadeia (-1)Achar nova posição vazia
a partir do finalposição 4
0 -2
1 -2
2 A2 6
3 A3 -1
4 -2
5 A5 9
6 B2 -1
7 A7 -1
8 A9 -1
9 B5 8
Encadeamento (coalescido)Posições disponíveis podem ser marcadas, por
exemplo, -2 em next-1 pode ser usado para indicar o final de uma cadeiaExemplo:
Inserir A7
Inserir C2
Colisão com A2
Segue-se para posição 6Posição 6 está ocupada Next indica fim da cadeia (-1)Achar nova posição vazia
a partir do finalposição 4
Inserir C2
Montar cadeia (posição 6 aponta para 4)
0 -2
1 -2
2 A2 6
3 A3 -1
4 C2 -1
5 A5 9
6 B2 4
7 A7-1
8 A9 -1
9 B5 8
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
0
1
2 A2
3 A3
4
5 A5
6
7
8
9
10
11
12
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)Achar posição no porão
0
1
2 A2
3 A3
4
5 A5
6
7
8
9
10
11
12
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)Achar posição no porãoIncluir link entre as posições
0
1
2 A2
3 A3
4
5 A5 12
6
7
8
9
10
11
12 B5
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)Achar posição no porãoIncluir link entre as posiçõesInserir B2 (colisão com A2)
0
1
2 A2
3 A3
4
5 A5 12
6
7
8
9
10
11
12 B5
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)Achar posição no porãoIncluir link entre as posiçõesInserir B2 (colisão com A2)Achar posição no porãoIncluir link entre as posições
0
1
2 A2 11
3 A3
4
5 A5 12
6
7
8
9
10
11 B2
12 B5
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)Achar posição no porãoIncluir link entre as posiçõesInserir B2 (colisão com A2)Achar posição no porãoIncluir link entre as posiçõesInserir A9 e B9
0
1
2 A2 11
3 A3
4
5 A5 12
6
7
8
9
10
11 B2
12 B5
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)Achar posição no porãoIncluir link entre as posiçõesInserir B2 (colisão com A2)Achar posição no porãoIncluir link entre as posiçõesInserir A9 e B9
0
1
2 A2 11
3 A3
4
5 A5 12
6
7
8
9 A9 10
10 B9
11 B2
12 B5
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)
Achar posição no porãoIncluir link entre as posiçõesInserir B2 (colisão com A2)
Achar posição no porãoIncluir link entre as posiçõesInserir A9 e B9
Inserir C2
0
1
2 A2 11
3 A3
4
5 A5 12
6
7
8
9 A9 10
10 B9
11 B2
12 B5
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)
Achar posição no porãoIncluir link entre as posiçõesInserir B2 (colisão com A2)
Achar posição no porãoIncluir link entre as posiçõesInserir A9 e B9
Inserir C2
0
1
2 A2 11
3 A3
4
5 A5 12
6
7
8 C2
9 A9 10
10 B9
11 B2 8
12 B5
Porão
Encadeamento (coalescido com porão)
Uso de área de transbordamento para armazenar chaves quando não há mais espaço na tabela.Esta área pode ser alocada dinamicamente
Exemplo:Inserir A2, A3 e A5
Inserir B5 (colisão com A5)
Achar posição no porãoIncluir link entre as posiçõesInserir B2 (colisão com A2)
Achar posição no porãoIncluir link entre as posiçõesInserir A9 e B9
Inserir C2
0 -2
1 -2
2 A2 11
3 A3 -1
4 -2
5 A5 12
6 -2
7 -2
8 C2 -1
9 A9 10
10 B9 -1
11 B2 8
12 B5 -1
Usando:-2 para posição vazia-1 para fim da cadeia
Porão
Endereçamento em baldeArmazenar na mesma posição os elementos que colidemAssociação de um balde a cada endereçoBalde
Bloco de espaço grande o suficiente para armazenar múltiplos itens
Não evita colisãoSe o balde está cheio
Próximo elemento pode ser armazenado no próximo balde vazioÁrea de transbordamento também pode ser utilizada
Neste caso, cada balde deve ser marcado para indicar se a busca deve ser continuada nessa áreaMarcador sim/não
Em conjunto com o marcador pode-se utilizar um ponteiro para indicar onde a lista inicia na área de transbordamento
Endereçamento em baldeExemplo: Balde e sondagem linear pela
próxima posição vaziaInserir A5, A2, A3, B5, A9, B2, B9, C2
Endereçamento em baldeExemplo: Balde e sondagem linear pela
próxima posição vaziaInserir A5, A2, A3, B5, A9, B2, B9, C2
0
1
2 A2
3 A3
4
5 A5
6
7
8
9
Endereçamento em baldeExemplo: Balde e sondagem linear pela
próxima posição vaziaInserir A5, A2, A3, B5, A9, B2, B9, C2
0
1
2 A2
3 A3
4
5 A5 B5
6
7
8
9
Endereçamento em baldeExemplo: Balde e sondagem linear pela
próxima posição vaziaInserir A5, A2, A3, B5, A9, B2, B9, C2
0
1
2 A2
3 A3
4
5 A5 B5
6
7
8
9 A9
Endereçamento em baldeExemplo: Balde e sondagem linear pela
próxima posição vaziaInserir A5, A2, A3, B5, A9, B2, B9, C2
0
1
2 A2 B2
3 A3
4
5 A5 B5
6
7
8
9 A9
Endereçamento em baldeExemplo: Balde e sondagem linear pela
próxima posição vaziaInserir A5, A2, A3, B5, A9, B2, B9, C2
0
1
2 A2 B2
3 A3
4
5 A5 B5
6
7
8
9 A9 B9
Endereçamento em baldeExemplo: Balde e sondagem linear pela
próxima posição vaziaInserir A5, A2, A3, B5, A9, B2, B9, C2
0
1
2 A2 B2
3 A3 C2
4
5 A5 B5
6
7
8
9 A9 B9
Endereçamento em baldeExemplo: Balde e transbordamento
Inserir A5, A2, A3, B5, A9, B2, B9, C2
Ao inserir C2 o balde está cheio, logo este é inserido na área de transbordamento
0
1
2 A2 B2
3 A3
4
5 A5 B5
6
7
8
9 A9 B9
C2
Área de transbordamento
Remoção Com um método de encadeamento
Remover elemento leva à remoção de um nó da lista ligada que contém o elemento
Para outros métodosRemoção pode exigir tratamento mais cuidadoso da resolução de
colisões, exceto no caso raro de uma função hashing perfeita ser utilizada
Exemplo:
Remover A4
0
1 A1
2 A2
3 B1
4
5 B4
6
7
8
9
Pesquisar B4
leva a resposta errada
0
1 A1
2 A2
3 B1
4 A4
5 B4
6
7
8
9
Remoção Com um método de encadeamento
Remover elemento leva à remoção de um nó da lista ligada que contém o elemento
Para outros métodosRemoção pode exigir tratamento mais cuidadoso da resolução de
colisões, exceto no caso raro de uma função hashing perfeita ser utilizada
Exemplo:
Remover A2
0
1 A1
2
3 B1
4
5 B4
6
7
8
9
Pesquisar B1
leva a resposta errada
0
1 A1
2 A2
3 B1
4
5 B4
6
7
8
9
RemoçãoPossível solução
Manter chaves removidas, marcando as posições como elementos não válidos
Busca não termina prematuramenteAo inserir nova chave, ela sobrescreve posição com
elemento não válido0
1 A1
2 A2 x
3 B1
4 A4 x
5 B4
6
7
8
9
RemoçãoPossível solução
Manter chaves removidas, marcando as posições como elementos não válidos
Busca não termina prematuramenteAo inserir nova chave, ela sobrescreve posição com
elemento não válido0
1 A1
2 A2 x
3 B1
4 A4 x
5 B4
6
7
8
9
Para muitas remoções e poucas inserções•A tabela se torna sobrecarregada de registros removidos•Necessidade de testar os elementos removidos
Registros devem ser expurgados depois de certo tempo e tabela reorganizada
RemoçãoPossível solução
Manter chaves removidas, marcando as posições como elementos não válidos
Busca não termina prematuramenteAo inserir nova chave, ela sobrescreve posição com
elemento não válido0
1 A1
2 B1
3
4 B4
5
6
7
8
9
Para muitas remoções e poucas inserções•A tabela se torna sobrecarregada de registros removidos•Necessidade de testar os elementos removidos
Registros devem ser expurgados depois de certo tempo e tabela reorganizada
Hashing para arquivos extensíveis
Todos os métodos anteriores previam tamanho fixo para alocação das chaves.
Existem várias técnicas propostas para implementar hashing em arquivos, os quais possuem tamanhos variáveis, com inserções e deleções constantes.
Podem ser divididas em Técnicas que usam diretórios
hashing expansível (Knott, 1971)hashing dinâmico (Larson, 1978)hashing extensível (Fagin et al, 1979)
Técnicas que não usam diretórioshashing virtual (Litwin, 1978)hashing linear (Litwin, 1980)
Hashing extensível Situação: balde (página primária) fica cheio. Porque não reorganizar o ficheiro duplicando o número de
baldes? Ler e escrever todas as páginas é dispendioso! Idéia: usar um diretório de ponteiros para baldes, duplique o
número de baldes através da duplicação do diretório, particionando justamente o balde que transbordou!
Um diretório é muito menor que um ficheiro, de modo que duplicá-lo é muito menos dispendioso. Só uma página de verbetes de dados é particionada.
O truque reside em como a função de hashing é ajustada!
Hashing extensível A função do diretório é conter informações que indiquem a
localização do balde de interesse.Um diretório é um arranjo de 2d endereços de baldes em
que d é profundidade global (profundidade do diretório).
O tamanho de cada balde é fixo O valor inteiro correspondente
aos primeiros d bits de uma
chave são utilizados.Supondo a profundidade do
diretório igual a 2 e a pseudo-chave igual a 101110, procuraremos na posição 10 pelo endereço do balde que contém a informação desejada.
Hashing extensível É possível ter mais de uma entrada no diretório apontando
para o mesmo balde. Cada balde armazena a informação de sua profundidade
A profundidade do balde é chamada de profundidade local.
A profundidade local indica quantos primeiros bits de cada pseudo-chave são comum a todos os elementos do balde.
A profundidade do balde pode ser menor ou igual à profundidade do diretório.
Hashing extensível Quando necessário, um diretório pode ser expandido
Isto ocorre quando “estoura” o espaço de endereços do diretório, ou seja, cada entrada aponta para um balde diferente de forma que não há como referenciar um novo balde.
Neste caso, o diretório dobra de tamanhoOu seja, a profundidade é incrementada em 1.
Inserção:Após obtida a pseudo-chave, pega-se os p primeiros
dígitos mais significativos da chave como índice para acessar uma posição do diretório.Por exemplo, se a pseudo-chave é 10100110 e a
profundidade é 3, acessaremos a posição 101, ou seja, 5 em decimal.
Daí, teremos 3 casos durante a inserção...
Hashing extensível: inserção Melhor caso
Há espaço no baldeA pseudo-chave é simplesmente inseridaExemplo: inserção da pseudo-chave 111010
Hashing extensível: inserção Caso intermediário
Não há espaço no balde encontrado, mas ele pode ser dividido, visto que mais de uma entrada no diretório faz referência ao balde no qual estamos tentando inserir.Equivalentemente, p do balde é menor que p do
diretórioUm novo balde é criado.As pseudo-chaves são redistribuídas entre o novo balde e
o originalA profundidade local dos dois baldes serão iguais à do
balde original incrementado de 1.
Hashing extensível: inserção Pior caso
Não há espaço no baldeEntrada no diretório faz referência única e exclusivamente
a um baldeOu seja, profundidade local é igual a profundidade
global.O diretório dobra de tamanho
Ou seja, profundidade global é incrementada de 1As pseudo-chaves são distribuídas entre os baldes do
novo diretório
Hashing extensível: remoção Ao remover uma entrada, temos que fazer duas verificações
Se é possível fundir o balde com um balde amigoSe o tamanho do diretório pode ser reduzido
Encontrando balde amigoPara haver um único balde amigo, a profundidade do
balde tem que ser a mesma do diretório.Dado um índice para o balde, o balde amigo é aquele que
difere apenas no último bit do índiceExemplo: Se um balde tem índice 000 e sua profundidade
é 3 e igual a do diretório, o balde amigo tem índice 001.Quando fundir?
Critério a cargo do programadorPode-se sempre tentar fundir os baldesPode-se definir um número mínimo de informação em
cada balde
Hashing extensível: remoção Reduzindo o diretório
Depois de fundir o balde, talvez o diretório possa ser reduzido
É possível quando cada balde é referenciado por pelo menos duas entradas do diretórioIsto é, todo p local é menor que o p global
Exercício Considere as seguintes pseudo-chaves já geradas por uma
função de hash h()00011, 10011, 11011, 01100, 00110, 00100, 01011, 11100, 10100
Pede-seMostrar a inserção, em ordem, de cada chave usando
abordagem de hashing extensívelMostrar a remoção das chaves 00100, 01100, 10100
ConsidereDiretório com profundidade 1 e balde com tamanho 2.
DicaNo início somente balde é criado e todas as entradas para
do diretório apontam para esse balde. A profundidade local é inicialmente 0.
Hashing linear O hashing extensível cresce de forma exponencial no
momento que cada balde precisa de mais registros Além disso, é necessário um dicionário para armazenar o
endereço de cada balde
O hashing linear cresce de forma mais lentaÉ criado um balde a cada momento que a tabela cresceNão é necessária uma tabela de enderaçamento
Dessa forma, não é necessário também refazer todos os indíces a cada crescimento
FuncionamentoManipulação de espaços através de diferentes funções de
hash aplicadas nos espaços disponíveis
Hashing linear Essa abordagem usa buckets que são estruturas com espaços
para mais de um registroEquivale a “baldes alocados em uma estrutura sequencial”
Cada bucket possui um tamanho fixo M, ou seja, armazena M chaves. Inicia-se a estrutura com um número fixo de buckets.
Caso o espaço do bucket estoure, é utilizado um bucket de overflow que pode ser implementado como uma lista encadeada
Um ponteiro p determina qual o bucket a ser duplicado
Hashing linear A criação de novo bucket é determinado pelo fator de carga da
estruturaOu seja, vários buckets podem conter mais registros do que
o espaço determinado e fazer uso de buckets de overflowA cada inserção, é verificado o fator de carga. Caso seja
maior do que um limite estipulado, um novo espaço de alocação é determinado.
O fator de carga é dado pela quantidade de registros inseridos divididos pela soma dos espaços possíveis nos buckets: FatorCarga = Total(registros) / M * Total(buckets)
Hashing linear: inserção Sendo N o tamanho da tabela hash (número inicial de
buckets), a inserção é dada pela fórmula h(k) = k mod 2g * N, sendo g iniciado de 0.
Ao inserir uma nova chave, aloca-a no bucket determinado pela fórmula acima
Caso o bucket esteja cheio, a chave é alocada no bucket de overflow.
Quando o fator de carga ultrapassa o máximo valor estabelecido, duplica-se o bucket apontado por p. O novo bucket é alocado no final da tabela e p é incrementado.
Os buckets duplicados são reorganizados e todos os dados dos dois buckets passam a obedecer a fórmula h
1(k)=k mod 2g+1 * N.
Hashing linear: inserção Suponha M=3, N=3 e fator de carga = 80%. Suponha a tabela
abaixo já preenchida com algumas chaves e p (ponteiro split) apontando para o índice 0 da tabela.
Como a tabela ainda não sofreu expansão (N=3 é o valor inicial), todas as chaves foram alocadas com a função
h(k) = k mod 2g * N, ou seja
h(k) = k mod 20 * 3 = k mod 3
Fator de carga da tabela é 75% = 9 chaves / 3 buckets com 3 espaços e 1 overflow em cada bucket.
Pode-se também calcular o fator de carga em relação ao número de espaços em buckets somente, sem o bucket de overflow.
Hashing linear: inserção Inserindo 10, o fator de carga vai para 83% (10/12)
Torna-se necessário criar um novo bucketO novo bucket é alocado no final da tabela. As chaves dos dois buckets são redistribuídas com a fórmula
h1(k) = k mod 2g+1 * N, ou seja
h1(k) = k mod 21 * 3 = k mod 6
O ponteiro p (split) é incrementado.
Hashing linear: inserção Inserindo 21, 36 e 25.
O novo bucket é alocado no final da tabela. As chaves dos dois buckets são redistribuídas com a fórmula
h1(k) = k mod 2g+1 * N, ou seja
h1(k) = k mod 21 * 3 = k mod 6
O ponteiro p (split) é incrementado.
Hashing linear: inserção Inserindo 27 e 37.
O fator de carga vai para 83%.As chaves dos dois buckets são redistribuídas com a fórmula
h1(k) = k mod 2g+1 * N, ou seja
h1(k) = k mod 21 * 3 = k mod 6
O ponteiro p (split) volta para a posição inicial.
Índice de p deve ser sempre menor que N!
Exercício Considere uma tabela com 4 buckets de tamanho 3 e fator de
carga 70%. Insira as seguintes chaves:
4, 8, 5, 9, 6, 7, 11, 13, 17, 15, 3, 18, 16, 36, 37
Assuma o fator de carga como sendo a razão entre os registros inseridos pela soma dos espaços dos buckets (sem contar os espaços dos buckets de overflow)