Estrutura de Dados - Tabelas de Dispersão
-
Upload
arnaldo-araujo -
Category
Documents
-
view
292 -
download
0
description
Transcript of Estrutura de Dados - Tabelas de Dispersão
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 1
HASH (v2) - 1
Tabelas de Dispersão (Tabelas de Dispersão (Hash TablesHash Tables))
q Sumário
lDefinição. Características.
lResolução de colisões: dispersão aberta e dispersão fechada. Teste quadrático.
lDesempenho de tabelas de dispersão.
l Interface de tabela de dispersão.
l Implementação de tabela de dispersão fechada com teste quadrático.
HASH (v2) - 2
TabelaTabela de de DispersãoDispersão
q Árvores binárias (de pesquisa) simples
l pior caso nas operações de manipulação é O(N)
l pior caso surge sistematicamente em usos correntes (ex: elementos previamenteordenados)
q Tabela de dispersão
l pesquisa baseada na geração de um inteiro a partir da chave
l tempo médio constante para inserção, remoção e pesquisa
l não requer gestão de memória especial nem comparação de elementos
l ocorrência do pior caso tem probabilidade muito baixa
q Aplicações
l tabelas de símbolos dos compiladores
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 2
HASH (v2) - 3
ResolverResolver colisõescolisões -- dispersãodispersão com com listaslistas
q Manter lista de elementos colocados na mesma entrada
l 1 lista com cabeçalho em cada entrada da tabela
l escolhe-se inserção a ocorrer na cabeça ou na cauda da lista
l exemplo com função de dispersão hash(x) = x mod 10 e inserção na cauda:
{0, 1, 4, 81, 64}
1º último
00
1
2
3
4
1
4
81
64
5
6
7
8
9
HASH (v2) - 4
ResolverResolver colisõescolisões -- dispersãodispersão abertaaberta
q Perante colisão procura-se célula alternativa
lTenta-se sequência de células H0(x), H1(x), H2(x), ...
lHi(x) = ( hash(x) + f(i) ) mod TamanhoTabela
q Teste linear: procurar sequencialmente a partir de H0
l primeira posição livre a seguir à inicial H0 é usada
- tenta-se H0+1, H0+2, ...
l pesquisa “dá a volta” no fim da tabela
l f(i) = i
q Teste quadrático
l procurar próxima posição livre a seguir a H com passo quadrático
- tenta-se H0+12, H0 + 22, H0 + 32, ...
l é preciso garantir que se pode percorrer a tabela toda - ver adiante
l f(i) = i2
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 3
HASH (v2) - 5
DesempenhoDesempenho nana dispersãodispersão com com listaslistas
q Factor de carga λ
l razão entre o número de elementos na tabela e o tamanho da tabela
q Dispersão com listas
l comprimento médio de cada lista é λ
l tempo médio de pesquisa: avaliação da função de dispersão + percurso na lista
- pesquisa sem sucesso: número médio de ligações a percorrer é λ- pesquisa com sucesso: número médio de ligações a percorrer é 1 + λ/2
l bom desempenho para λ próximo de 1
HASH (v2) - 6
DesempenhoDesempenho nana DispersãoDispersão AbertaAberta (1)(1)q Dispersão abertal com função linear
- número de tentativas para inserção e para pesquisa semsucesso:
1/2 ( 1 + 1/(1- λ)2 )- número de tentativas para pesquisa com sucesso:
1/2 ( 1 + 1/(1- λ) )l caso ideal (sem clustering)
- número de tentativas para inserção e para pesquisa semsucesso:
1/(1- λ)- número de tentativas para pesquisa com sucesso:
1/ λ ln (1/(1- λ) )l função quadrática elimina clustering primário
- na prática, eficiência próxima do caso ideal
λ= 0.2Ins, Falha: 1.3Sucesso: 1.1 λ= 0.8Ins, Falha: 13Sucesso: 3
λ= 0.2Ins, Falha: 1.3Sucesso: 1.1 λ= 0.8Ins, Falha: 5.0Sucesso: 2.0
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 4
HASH (v2) - 7
DesempenhoDesempenho nana DispersãoDispersão AbertaAberta (2)(2)
1
10
100
1000
10000
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1,0
factor de carga
nº
de
po
siçõ
es a
ced
idas
par
a in
serç
ão e
pes
qu
isa
função linear, elementoinexistente
função linear, elementoexistente
caso ideal (semclustering), elementoinexistentecaso ideal (semclustering), elementoexistente
235
13
com dispersão aberta, o factor de carga não deve exceder 0,5 para se garantir um bom desempenho!
HASH (v2) - 8
DispersãoDispersão com com TesteTeste QuadráticoQuadrático
q Teorema
Usando teste quadrático e uma tabela cujo tamanho é um número primo, um novo elemento pode sempre ser inserido se a tabela não estiver preenchida a mais de 50%
-Mostra-se que as primeiras Tam/2 posições alternativas são todas distintas, por redução ao absurdoh(x) + i2 (mod Tam) = h(x) + j2 (mod Tam) com i≠j e 0 < i,j < Tam/2
h(x) + i2 = h(x) + j2 (mod Tam)i2 = j2 (mod Tam)i2 - j2 = 0 (mod Tam)( i-j )( i+j ) = 0 (mod Tam) (o mesmo que ( i-j )( i+j ) = k Tam)
Sendo Tam número primo, ( i-j ) ou ( i+j ) tem de ser 0 (mod Tam). Sendo i e j distintos, ( i-j ) não é 0; sendo 0 < i,j < Tam/2, ( i+j ) também não é 0. Então as primeiras Tam/2 posições alternativas são distintas
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 5
HASH (v2) - 9
DispersãoDispersão com com TesteTeste QuadráticoQuadrático
q Teorema
A geração de posições alternativas no teste quadrático pode ser feita com apenas uma multiplicação
Seja H0 a posição inicial, Hi-1 a última posição calculada e Hi a próximaHi = H0 + i2 (mod Tam) Hi - Hi-1 = i2 - (i-1)2 (mod Tam)Hi = Hi-1 + 2i - 1 (mod Tam)O valor de Hi pode assim ser obtido sem operações pesadas de multiplicaçãoPara calcular o mod:2i-1 é menor que TamHi-1 + 2i - 1 ou é menor que Tam (caso em que o mod se dispensa)
ou é pouco maior que Tam (caso em que o mod se reduz a subtrair Tam)
HASH (v2) - 10
Eliminação com Dispersão AbertaEliminação com Dispersão Abertaq Para eliminar um elemento da tabela, marca-se como apagado, para que
posteriores pesquisas funcionem correctamente
q 3 estados: posição ocupada, livre ou marcada como apagada
l posição activa: ocupada ou marcada como apagada
q Exemplo, com hash(x) = x mod 10
0
1
2
3
4
5
6
7
8
9
13add(13)
0
1
2
3
4
5
6
7
8
9
13add(23)
23
0
1
2
3
4
5
6
7
8
9
13remove(13)
23
0
1
2
3
4
5
6
7
8
9
13contains(23)
23
como a posição está marcada como apagada, procura na posição seguinte
marca posiçãocomoapagada
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 6
HASH (v2) - 11
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSetpackage weiss.util;import java.io.Serializable;
public class HashSet extends AbstractCollection implements Set{
private static final int DEFAULT_TABLE_SIZE = 101;private int currentSize = 0;private int occupied = 0;private int modCount = 0;private HashEntry [ ] array;
public HashSet( ){
allocateArray( DEFAULT_TABLE_SIZE );clear( );
}
public HashSet( Collection other ){
allocateArray( other.size( ) * 2 );clear( );
Iterator itr = other.iterator( );while( itr.hasNext( ) )
add( itr.next( ) ); }
HASH (v2) - 12
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSetpublic int size( ){
return currentSize;}
/*** This method is not part of standard Java 1.2.* Like contains, it checks if x is in the set.* If it is, it returns the reference to the matching* object; otherwise it returns null.*/
public Object getMatch( Object x ){
int currentPos = findPos( x );if( array[ currentPos ] == null )
return null;return array[ currentPos ].element;
}
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 7
HASH (v2) - 13
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet/**
* Tests if some item is in this collection.* @param x any object.* @return true if this collection contains an item equal to x.*/
public boolean contains( Object x ){
return isActive( array, findPos( x ) );}
/*** Tests if item in pos is active.* @param pos a position in the hash table.* @param arr the HashEntry array (can be oldArray during rehash).* @return true if this position is active.*/
private static boolean isActive( HashEntry [ ] arr, int pos ){
return arr[ pos ] != null && arr[ pos ].isActive;}
HASH (v2) - 14
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
/*** Adds an item to this collection.*/
public boolean add( Object x ){
int currentPos = findPos( x );if( isActive( array, currentPos ) )
return false;
array[ currentPos ] = new HashEntry( x, true );currentSize++;occupied++;modCount++;
if( occupied > array.length / 2 ) rehash( );
return true; }
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 8
HASH (v2) - 15
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
/*** Private routine to perform rehashing.* Can be called by both add and remove.*/
private void rehash( ){
HashEntry [ ] oldArray = array;
// Create a new, empty tableallocateArray( nextPrime( 4 * size( ) ) );currentSize = 0;occupied = 0;
// Copy table overfor( int i = 0; i < oldArray.length; i++ )
if( isActive( oldArray, i ) ) add( oldArray[ i ].element );
}
HASH (v2) - 16
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
/*** Removes an item from this collection.*/
public boolean remove( Object x ){
int currentPos = findPos( x );if( !isActive( array, currentPos ) )
return false;
array[ currentPos ].isActive = false;currentSize--;modCount++;
if( currentSize < array.length / 8 )rehash( );
return true;}
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 9
HASH (v2) - 17
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
public void clear( ){
currentSize = occupied = 0;modCount++;for( int i = 0; i < array.length; i++ )
array[ i ] = null;}
public Iterator iterator( ){
return new HashSetIterator( );}
HASH (v2) - 18
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
private class HashSetIterator implements Iterator{
private int expectedModCount = modCount;private int currentPos = -1;private int visited = 0;
public boolean hasNext( ){
if( expectedModCount != modCount )throw new ConcurrentModificationException( );
return visited != size( ); }
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 10
HASH (v2) - 19
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
public Object next( ){
if( !hasNext( ) )throw new NoSuchElementException( );
do{
currentPos++;} while( currentPos < array.length &&
!isActive( array, currentPos ) );
visited++;return array[ currentPos ].element;
}
HASH (v2) - 20
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
public void remove( ){
if( expectedModCount != modCount )throw new ConcurrentModificationException( );
if( currentPos == -1 || !isActive( array, currentPos ) )throw new IllegalStateException( );
array[ currentPos ].isActive = false;currentSize--;visited--;modCount++;expectedModCount++;
}}
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 11
HASH (v2) - 21
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
private static class HashEntry implements Serializable{
public Object element; // the elementpublic boolean isActive; // false if marked deleted
public HashEntry( Object e ){
this( e, true );}
public HashEntry( Object e, boolean i ){
element = e;isActive = i;
}}
HASH (v2) - 22
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
private int findPos( Object x ){
int collisionNum = 0;int currentPos = ( x == null ) ? 0
: Math.abs( x.hashCode( ) % array.length );
while( array[ currentPos ] != null ){
if( x == null ){
if( array[ currentPos ].element == null )break;
}else if( x.equals( array[ currentPos ].element ) )
break;
currentPos += 2 * ++collisionNum - 1; // Compute ith probeif( currentPos >= array.length ) // Implement the mod
currentPos -= array.length;}
return currentPos;}
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 12
HASH (v2) - 23
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
private void allocateArray( int arraySize ){
array = new HashEntry[ arraySize ];}
private static int nextPrime( int n ){
if( n % 2 == 0 )n++;
for( ; !isPrime( n ); n += 2 );
return n;}
HASH (v2) - 24
Tabela de Dispersão em Tabela de Dispersão em HashSetHashSet
private static boolean isPrime( int n ){
if( n == 2 || n == 3 )return true;
if( n == 1 || n % 2 == 0 )return false;
for( int i = 3; i * i <= n; i += 2 )if( n % i == 0 )
return false;
return true;}
}
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 13
HASH (v2) - 25
Implementação de Dicionários (Implementação de Dicionários (mapsmaps) ) com Tabelas de Dispersão (1)com Tabelas de Dispersão (1)
q Um dicionário, ou função finita definida em extensão (map), é um conjunto de pares (chave, valor) tal que não existem dois pares com chaves iguais
lTanto a chave como o valor podem ser de um tipo arbitrariamente complexo
lExemplo: chave – nº da conta; valor – nome do dono da conta
- É função (finita):
{ (1, "João"), (3, "João"), (5, "Rui")}
- Não é função (finita)
{ (1, "João"), (1, "Ana "), (5, "Rui")}
(mas é uma relação binária)
chave valor
xxx
xx
chave valor
x
x
x
xx
HASH (v2) - 26
Implementação de Dicionários (Implementação de Dicionários (mapsmaps) ) com Tabelas de Dispersão (2)com Tabelas de Dispersão (2)
q Implementação com tabela de dispersão (classe HashMap)
l um elemento da tabela é um par (chave, valor) (classe Pair)
l a função de dispersão (hashCode) e a função de comparação (equals) baseiam-se apenas na chave do par
l as funções de pesquisa (containsKey, get) e eliminação (remove) têm como argumento a chave
- funções implementadas na classe abstracta MapImpll a função de inserção (put) tem como argumentos a chave e o valor
- função implementada na classe abstracta MapImpll pode-se modificar o valor correspondente a uma dada chave (put)
- função implementada na classe abstracta MapImpl
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 14
HASH (v2) - 27
Tabela de Dispersão em Tabela de Dispersão em HashMapHashMap
package weiss.util;
/*** Hash table implementation of the Map.*/
public class HashMap extends MapImpl{
public HashMap( ){
super( new HashSet( ) );}
public HashMap( Map other ){
super( other );}
HASH (v2) - 28
Tabela de Dispersão em Tabela de Dispersão em HashMapHashMap
protected Map.Entry makePair( Object key, Object value ){
return new Pair( key, value );}
protected Set makeEmptyKeySet( ){
return new HashSet( );}
protected Set clonePairSet( Set pairSet ){
return new HashSet( pairSet );}
LEIC-FEUP 2001/2002Algoritmos e Estruturas de Dados 1
Cristina Ribeiro Hash- 15
HASH (v2) - 29
Tabela de Dispersão em Tabela de Dispersão em HashMapHashMap
private static final class Pair implements Map.Entry{
public Pair( Object k, Object v ){
key = k;value = v;
}
public Object getKey( ){
return key;}
public Object getValue( ){
return value;}
HASH (v2) - 30
Tabela de Dispersão em Tabela de Dispersão em HashMapHashMap
public int hashCode( ){
return key.hashCode( );}
public boolean equals( Object other ){
if( other instanceof Map.Entry )return getKey( ).equals(
((Map.Entry) other).getKey() );else
return false; }
private Object key;private Object value;
}}