Você está na página 1de 30

Estruturas de Dados em Java Dicionrio

Prof. Jailton Carlos Jailton.paiva@ifrn.edu.br


07/03/2012 1

Dicionrio
Continer onde objetos genricos so inseridos, removidos e acessados atravs de uma chave Cada item de um dicionrio um par chaveelemento
O elemento representa as informaes teis armazenadas A chave representa o meio de acesso s informaes

As chaves de um dicionrio podem ser repetidas


Dicionrio 2

Exemplos
Agenda
Dados: informaes pessoais, nome, fone, email, etc Chave: nome

Carto de crdito
Dados: nmero, titular, limite, saldo disponvel Chave: nmero

Conta bancria
Dados: nmero, titular, saldo, data de abertura Chave: nmero

Janelas em um ambiente grfico


Dados: ttulo, dimenso, menu, fonte, cor Chave: handle
Dicionrio 3

Tipos de Dicionrios
Dicionrio no ordenado
As chaves so armazenadas na ordem de insero O comparador implementa apenas uma verificao de igualdade no acesso e na remoo de elementos

Dicionrio ordenado
As chaves so armazenadas segundo algum critrio O comparador implementa um relao de ordem total nas operaes de acesso, insero e remoo Dicionriode elementos 4

Implementaes
Dicionrio no ordenado
Simples: Arquivo de Log
Vetor, Lista ou Sequncia no ordenada

Otimizada: Tabela de hash

Dicionrio ordenado
Simples: Tabela de pesquisa
Vetor ordenado

Otimizada: skip-list
Dicionrio 5

Dicionrio No-Ordenado
Mtodos genricos
int size() boolean isEmpty()

Mtodos de atualizao
Entry<K,V> insert (K key, V value)
insere o novo elemento value com chave key, retornando o elemento criado.

Entry<K,V> remove (Entry<K,V> e)


remove o elemento e do dicionrio, retornado o elemento removido ou null se e no for encontrado.

Dicionrio

Dicionrio No-Ordenado
Mtodos de acesso
Iterable<Entry<K,V>> entries()
Retorna uma coleo dos elementos chave-valor do dicionrio.

Entry<K,V> find (K key)


retorna o elemento com chave key, sem remov-lo, seno encontr-lo, retorna null;

Iterable<Entry<K,V>> findAll (K key)


retorna uma coleo contendo todos os elementos com chave igual a key.

Dicionrio

Dicionrio com Chaves Inteiras


Operao insert(5, A) insert(7, B) insert(2, C) insert(2, E) find(7) find(4) (7,B) null Sada Incio Dicionrio Fim (5, A) (5, A) (7, B) (5, A) (7, B) (2, C) (5, A) (7, B) (2, C) (2, E) (5, A) (7, B) (2, C) (2, E) (5, A) (7, B) (2, C) (2, E)

find (2)
findAll(2) remove(find(5)) find(5)

(2,C)
{(2,C), (2,E)} (5,A) null
Dicionrio

(5, A) (7, B) (2, C) (2, E)


(5, A) (7, B) (2, C) (2, E) (7, B) (2, C) (2, E) (7, B) (2, C) (2, E)
8

Interface Dictionary em Java


public interface Dictionary<K,V> { public int size(); public boolean isEmpty(); public Entry<K,V> find(K key) throws InvalidKeyException; public Iterable<Entry<K,V>> findAll(K key) throws InvalidKeyException; public Entry<K,V> insert(K key, V value) throws InvalidKeyException; public Entry<K,V> remove(Entry<K,V> e) throws InvalidEntryException; public Iterable<Entry<K,V>> entries(); }
Dicionrio 9

DNO - Implementao com Arquivos de Log


A implementao de dicionrios com arquivos de log utiliza uma sequncia no ordenada
Os itens (chaves-elementos) so inseridos no fim da sequncia utilizando o mtodo insertLast

Desempenho
Inseres ocorrem em tempo constante O(1): insert Remoes e localizaes ocorrem em tempo linear O(n): remove, find, findAll

Aplicaes
Dicionrios pequenos ou que requerem basicamente operaes de insero Ex: Arquivos de inicializao e Logs de sistemas operacionais
Dicionrio 10

DNO - Implementao com Arquivos de Log


Assume-se que a sequncia S, usada para um dicionrio baseado em sequncia, implementada com uma lista duplamente endadeada.
Algorithm findAll(k): Entrada: Uma chave k Sada: Uma coleo de elemtnos com chave igual a k Cria uma sequncia L inicialmente vazia. para cada elemento e em D.Entries() faa se e.getKey() = k ento L.addLast|(e) retorna L { os elementos em L so os elementos selecionados} Algorithm insert(k,v): Entrada: Uma chave k e valor v Sada: o elemento (k,v) adicionado em D Cria um novo elemento e= (k,v) Chama S.addLast(e) { S est desordenado} Dicionrio 11 retorna e;

DNO - Implementao com Arquivos de Log


Algorithm remove(e): Entrada: um elemento e Sada: O elemento removido e ou nulo se e no estiver em D. para cada posio p de S.positions() faa se p.element() = e ento S.remove(e) retorna e; retorna nulo {no existe elemento e em D} Algorithm entries: Entrada: Nenhuma Sada: uma coleo dos itens do dicionrio em D. retorna S; {os elementos de S o os itens de D}

Dicionrio

12

DNO - Implementao com Tabela de Hash


A implementao otimizada de dicionrios utiliza uma estrutura chamada tabela de hash
Utiliza uma funo (funo hash) para converter as chaves dos itens do dicionrio em nmeros inteiros (cdigo hash) O cdigo hash do item deve possibilitar o acesso ao elemento em tempo constante Os itens do dicionrio so armazenados em um arranjo, cujos ndices esto associados aos cdigos hash das chaves

Desempenho
Inseres, localizaes e remoes executam em tempo esperado constante O(1)
Dicionrio 13

Tabela de Hash
Componentes
Arranjo de Buckets
Arranjo de N objetos que referenciam Itens (chaveelemento)

Funo de Hash
Codificar a chave em um inteiro entre 0 e N-1 0 1 2 3 4
Dicionrio

025-612-0001


451-229-0004
14

981-101-0004

Arranjo de Buckets
O arranjo de buckets um arranjo A de tamanho N, em que cada clula considerada como um bucket (ou seja, continer para pares chave-elemento)
Cada clula do arranjo pode conter um ou mais elementos A situao ideal ocorre quando existe apenas um elemento por clula
1, c B 0 1 2 3 3, a 4 5 3, b 6 7 8 9 7, d 7, g 7, e

Dicionrio

15

Arranjo de Buckets
O inteiro N determina a capacidade do arranjo e, por conseguinte, os possveis ndices e valores da chaves = [0, N-1]
Se as chaves forem inteiros bem distribudos no intervalo [0, N-1], o item (k, e) inserido no bucket A[k] Se as chaves forem inteiros fora do intervalo de ndices necessrio mape-las para o intervalo requerido Se as chaves no forem inteiros necessrio codific-las e mape-las Se as chaves no forem nicas, dois elementos podem ser mapeados para o mesmo bucket, gerando uma coliso que precisa ser tratada
Dicionrio 16

Anlise do Arranjo de Bucket


Se as chaves so nicas, coliso no problema As chaves (codificadas ou no) possuem valores entre 0 e N-1 permitindo acesso aos buckets em tempo constante O(1)
Se no existem colises, insero, localizao e remoo ocorrem em tempo constante O(1) Se existem colises, o tempo de execuo das operaes proporcional ao nmero de elementos no bucket

Desvantagens
O espao utilizado pelo dicionrio proporcional a N e no ao nmero de itens no dicionrio n

Dicionrio

17

Funo de Hash
A funo de hash objetiva mapear uma chave genrica k em um inteiro no intervalo [0, N-1]
A idia utilizar o valor da funo de hash h(k) como ndice no arranjo de buckets O item (k, e) inserido no bucket A[h(k)]

A funo de hash boa se ela mapeia as chaves do dicionrio minimizando as colises

Dicionrio

18

Funo de Hash
A funo de hash realizada em duas etapas
Mapear a chave k em um inteiro: Cdigo hash: h1(k) Mapear o cdigo hash entre [0, N-1]: Mapa de Compresso: h2(k)

Objetos arbitrrios

cdigo de hash

... -2 -1 0 1 2 ...
Funo de compresso

0 1 2 3 ...
Dicionrio 19

N-1

Cdigo Hash
O objetivo mapear uma chave arbitrria em um nmero inteiro
O cdigo no precisa estar no intervalo [0, N-1] A funo hash deve evitar colises, gerando cdigos distintos para chaves diferentes A funo hash deve gerar o mesmo cdigo para chaves iguais

Dicionrio

20

Cdigo Hash em Java


Endereo de memria
Interpreta o endereo de memria da chave como inteiro (usado pelo mtodo hashCode de Object) Bom no geral, mas pode ter cdigos diferentes para a mesma chave (String, Nmeros, etc)

Converso para inteiros


Interpreta os bits da chave como um inteiro Adaptvel para chaves cujo tamanho menor ou igual ao nmero de bits de um inteiro (byte, short, int e float em Java). No caso de float, converte-se utilizando a chamada floatToIntBits(x).
Dicionrio 21

Cdigo Hash em Java


Soma de componentes
static int hashCode(long i) { return (int) ( (i >>32) + (int) i ); }

Para tipos long e double, cuja representao em bits duas vezes maior do que um cdigo de hash, a converso iria ignorar metade da informao origninal. Uma alternativa somar a representao inteira dos bits de mais alta ordem com os de mais baixa ordem.
Divide o valor long em dois dados de 32 bits e realiza a soma static int hashCode(long i) { return (int) ( (i >>32) + (int) i ); }
Dicionrio 22

Cdigo Hash em Java


Cdigos hash polinomiais
Somar os componentes no uma boa escolha para cadeias de caracteres ou outros objetos longos que podem ser vistos como tuplas da forma (x0, x1, , xk-2, xk-1) ) pois produz muitas colises indesejveis
Exemplo: temp01 e temp10; stop, pots, spot e tops

Define o cdigo hash como: h1(k) = x0ak-1 + x1ak-2 + + xk-2 a + xk-1

Dicionrio

23

Cdigo Hash em Java


Cdigos hash polinomiais
Aplicao
Strings Valores de a = 33, 37, 39, ou 41 produzem menos de sete colises em 50 mil palavras da lngua inglesa

static int hashCode(String s) { int hash=0; for (int i=0; i< s.length(). i++ ) { hash += s.charAt(i) * Math.pow(33, i) ; return hash; } Dicionrio 24

Mapa de Compresso
O objetivo mapear o cdigo hash gerado na primeira etapa da funo hash para um inteiro entre 0 e N-1 Funes de compresso
Mtodo da diviso

h2(k) = |k| % N Mtodo da multiplicao, adio e diviso (MAD) h2(k) = |ak + b| % N onde: k o cdigo hash N um nmero primo (minimiza as colises) A >0 (chamado de fator de ativao) um inteiro tal que a % N != 0 b >=0 (chamado shift) so constantes inteiras escolhidas aleatoriamente.
25

Dicionrio

Tratamento de Colises
Colises ocorrem quando duas chaves distintas k1 e k2 so tais que h(k1) = h(k2), ou seja, possuem o mesmo cdigo hash
As colises impedem que inseres, localizaes e remoes em uma tabela hash sejam feitas em O(1) usando A[h(k)]

Estratgias de tratamento
Encadeamento separado
Utiliza uma lista, vetor ou sequncia em cada ndice do arranjo A

Endereamento aberto
Utiliza clulas vazias do arranjo A, armazenando os elementos em ndices vizinhos aos ndices dados pelo cdigo hash

Dicionrio

26

Encadeamento Separado
Cada clula do arranjo A uma referncia para um vetor, lista ou sequncia de itens, onde os elementos com mesmo cdigo hash so armazenados Exemplo
Chaves inteiras Mapa de compresso: h(k) = k%13
0 1 2 3 4 5 6 7 8 9 10 11 12

41

28

54

18

36

10

90

12

38

25

Dicionrio

27

Endereamento Aberto
0 1 2 3 4 5 6 7 8 9 10

13
insero de k = 15

26

37 16

Quando o cdigo hash calculado, se a clula A[h(k)] est ocupada, uma outra clula do arranjo utilizada de acordo com um teste
Teste linear: A[(h(k)+i)%N] utilizada, com i = 1, 2, 3, ... Teste quadrtico: A[(h(k)+i)%N] utilizada, com i = 1, 4, 9, ... Hashing duplo: A[(h(k)+jh(k))%N] utilizada, com j = 1, 2, 3, ...

As operaes de insero, localizao e remoo tornam-se mais complexas e a utilizao do objeto especial AVAILABLE, usado para substituir os elementos removidos, recomendada Exemplo: Chaves inteiras, Mapa de compresso: h(k) = k%11 Dicionrio

28

Fator de Carga e Rehash


Fator de carga ()
Relao entre o nmero de elementos n do dicionrio e o tamanho do arranjo de buckets N

Anlise de experimentos
Endereamento aberto: < 0.5
Agrupamentos crescem e testes do a volta no arranjo

Encadeamento separado: < 0.9


Sequncias referenciadas pelas clulas do arranjo ficam com muitos elemento, retardando as operaes

Rehash dobra o tamanho do arranjo de buckets


Objetivo: reduzir o fator de carga Re-mapeamento de todas as chaves no arranjo original

Dicionrio

29

Referncia Bibliogrfica
Goodrich M., Tamassia R. Estrutura de Dados e Algoritmos em Java. 4 ed. Bookman, 2007.
Java.datastructures.net

Pilhas e Filas

30

Você também pode gostar