Estrutura de Dados - Tabelas de Dispersão

15
HASH (v2) - 1 Tabelas de Dispersão ( Tabelas de Dispersão ( Hash Tables Hash Tables) q Sumário l Definição. Características. l Resolução de colisões: dispersão aberta e dispersão fechada. Teste quadrático. l Desempenho 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 Tabela Tabela de de Dispersão Dispersã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 previamente ordenados) 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 nemcomparação de elementos l ocorrência do pior caso tem probabilidade muito baixa q Aplicações l tabelas de símbolos dos compiladores

description

Material sobre a estrutura de dados tabela de dispersão

Transcript of Estrutura de Dados - Tabelas de Dispersão

Page 1: 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

Page 2: Estrutura de Dados -  Tabelas de Dispersão

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

Page 3: Estrutura de Dados -  Tabelas de Dispersão

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

Page 4: Estrutura de Dados -  Tabelas de Dispersão

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

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

Page 5: Estrutura de Dados -  Tabelas de Dispersão

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

Page 6: Estrutura de Dados -  Tabelas de Dispersão

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;

}

Page 7: Estrutura de Dados -  Tabelas de Dispersão

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; }

Page 8: Estrutura de Dados -  Tabelas de Dispersão

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;}

Page 9: Estrutura de Dados -  Tabelas de Dispersão

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( ); }

Page 10: Estrutura de Dados -  Tabelas de Dispersão

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++;

}}

Page 11: Estrutura de Dados -  Tabelas de Dispersão

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;}

Page 12: Estrutura de Dados -  Tabelas de Dispersão

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;}

}

Page 13: Estrutura de Dados -  Tabelas de Dispersão

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

Page 14: Estrutura de Dados -  Tabelas de Dispersão

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 );}

Page 15: Estrutura de Dados -  Tabelas de Dispersão

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;

}}