Adriana Libório Fernandes Lins Arthur Cavalcanti Alem Átila Valgueiro Malta Moreira Flavio Juvenal da Silva Júnior Gustavo Cauê Silva.

Slides:



Advertisements
Apresentações semelhantes
LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello.
Advertisements

HASHING Katia Guimarães julho/2002
Listas Lineares Estrutura que permite representar um conjunto de dados de forma a preservar a relação de ordem linear. Uma lista linear é composta de nós,
Organização e Recuperação da Informação
Arquivos Extensíveis.
Pesquisa em Memória Primária
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
Pesquisa em Memória Primária - Hashing
Pesquisa em Memória Primária – Árvores de Busca
Medida do Tempo de Execução de um Programa
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
Pesquisa em Memória Primária – Árvores de Busca
Medida do Tempo de Execução de um Programa
Pesquisa em Memória Primária
David Menotti Estruturas de Dados I DECOM – UFOP
Hashing (Espalhamento)
Indexação e Hashing Muitas consultas referenciam apenas uma pequena porção dos registros em uma tabela. Portanto necessitamos ser capaz de localizar estes.
AED – Algoritmos e Estruturas de Dados
Pesquisa em Memória Primária
Análise Léxica Supondo o trecho de programa abaixo:
Listas com Ponteiros Listas encadeadas Listas circulares.
Robson Godoi / Sandra Siebra
Listas Encadeadas.
Marco Antonio Montebello Júnior
ALGORITMOS E ESTRUTURAS DE DADOS
Listas Encadeadas Raquel O. Prates, Luiz Chaimowicz, Jussara Almeida
Pesquisa em memória primária: hashing
Pesquisa em Memória Primária
INTELIGÊNCIA ARTIFICIAL
Algorítmos e estrutura de dados III
Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Algorítmos e estrutura de dados III Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação
Aula 03 – BCC202 Análise de Algoritmos (Parte 1) Túlio Toffolo www
Hashing - Espalhamento
Hash tables Fábio Nakano.
Faculdade de Informática e Tecnologia de Pernambuco ESTRUTURA DE DADOS
© Copyright 2007 Algoritmos e Estruturas de Dados - Todos os direitos reservados Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto.
Estruturas de Dados Aula 11: TAD Pilha
Árvore Binária de Busca
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática Disciplina: Estrutura de Dados Professor: Cheli dos S. Mendes da Costa Listas.
Tabelas Hash Prof. Túlio Toffolo
Estruturas de Dados Aula 17: Estruturas Genéricas
Estruturas de Dados Aula 15: Árvores
– Aula 20 Adaptado por Reinaldo Fortes para o curso de
Tabela Hash Alunos : Gustavo Jorge Zanin nºUSP
Lista Linear Base para outras estruturas
Conjuntos Algoritmos e Estruturas de Dados - IF672
© Copyright 2003 Algoritmos e Estruturas de Dados - Todos os direitos reservados Grafos IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Adriana Libório.
Árvores AVL Algoritmos e Estruturas de Dados - IF672
Aula Prática 5 Monitoria IP/CC (~if669). Roteiro 1. 1.Recursão 2. 2.Escopo de Variáveis 3. 3.Arrays 4. 4.Strings.
Copyright 1998, Departamento de Informática da UFPE. Todos os direitos reservados sob a legislação em vigor. Variáveis e métodos estáticos, Passagem de.
JAVA – Fila ATAI.
© Copyright 2007 Algoritmos e Estruturas de Dados - Todos os direitos reservados Estruturas de Dados Dinâmicas IF672 - Algoritmos e Estruturas de Dados.
© Copyright 2008 Algoritmos e Estruturas de Dados 1 IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Adriana Libório Fernandes Lins Arthur Cavalcanti.
IF672 cc Algoritmos e Estruturas de Dados
Estrutura de dados Aula 6 - hash
Profa. Juliana Mafra ESTRUTURA DE DADOS 30 de Setembro de 2009 Faculdade de Informática e Tecnologia de Pernambuco.
Programação Dinâmica IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto Gomes.
Hashing (Tabela de Dispersão)
Adriana Libório Fernandes Lins Arthur Cavalcanti Alem Átila Valgueiro Malta Moreira Flavio Juvenal da Silva Júnior Gustavo Cauê Silva.
© Copyright 2003 Algoritmos e Estruturas de Dados - Todos os direitos reservados Busca em Grafos IF672 - Algoritmos e Estruturas de Dados CIn - UFPE ©
Arrays Outline 7.1 Introdução 7.2 Arrays 7.3 Declarando e Criando Arrays 7.4 Exemplos usando arrays 7.5 Ordenando arrays 7.6 Procurando em.
© Copyright 2007 Algoritmos e Estruturas de Dados - Todos os direitos reservados Ponteiros IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Murilo Raphael.
Adriana Libório Fernandes Lins Arthur Cavalcanti Alem Átila Valgueiro Malta Moreira Flavio Juvenal da Silva Júnior Gustavo Cauê Silva Botelho Matheus Bispo.
© Copyright 2003 Algoritmos e Estruturas de Dados - Todos os direitos reservados Busca Gulosa em Grafos IF672 - Algoritmos e Estruturas de Dados CIn -
Capítulo 4. Conjuntos  Introdução  Principais operações de conjuntos  Principais interfaces de conjuntos  A interface Collection  A interface Iterator.
Alocação Dinâmica Dilvan Moreira. Objetivos  Entender o que são e como usar:  Gerenciamento de Memória  Alocação Dinâmica em C.
Entrada e Saída de Dados com Arquivos – Java
Estruturas de Dados Dinâmicas
Transcrição da apresentação:

Adriana Libório Fernandes Lins Arthur Cavalcanti Alem Átila Valgueiro Malta Moreira Flavio Juvenal da Silva Júnior Gustavo Cauê Silva Botelho Matheus Bispo Arrais de Souza Murilo Raphael de Souza Lira Rafael Alberto Gomes Pereira Lima Rafael Brandão Lobo Rafael Loureiro de Carvalho Tiago Carneiro Pessoa Canto Vinicius Miranda Cesar

Mapeamento Associação de cada objeto de um tipo a uma chave, permitindo a indexação. Ex: String  Inteiro Útil para construir estruturas de armazenamento com custo reduzido em tempo (acesso direto). “Algoritmos” 253 “Hashing” 54 “Árvore” 784

Mapeamento Ex: Tabuleiro de Jogo da Velha X O = 0 = 1 = 2 X OO X XOOX = 1 x x x x 3 6 = = 1272

Mapeamento Cada tabuleiro é mapeado em um valor único, entre 0 e Deste modo, é possível recuperar o tabuleiro a partir de sua chave. Através da chave, podemos indexar os objetos, por exemplo, em um array, caso o tamanho seja suficiente: XOXOOO OOO OOO XOO OOO OOO 4 XXOX 56 O

Hashing Entretanto, se o número de chaves possíveis for muito grande, é preciso distribuir os valores possíveis entre as posições disponíveis (de 0 a length-1). Esta técnica é chamada de hashing, e função de mapeamento chave-posição é a função hash. Ex: uma função hash simples é tirar o resto da divisão pelo tamanho da tabela h(chave) = chave % array.length

Por que usar Hashing? Estruturas de busca sequencial levam tempo até encontrar o elemento desejado. Ex: Arrays e listasEx: Árvores

Por que usar Hashing? Em algumas aplicações, é necessário obter o valor com poucas comparações, logo, é preciso saber a posição em que o elemento se encontra, sem precisar varrer todas as chaves. A estrutura com tal propriedade é chamada de tabela hash ? 20 % 8 = ? 45 % 8 = 5

Colisões Devido ao fato de existirem mais chaves que posições, é comum que várias chaves sejam mapeadas na mesma posição. Quando isto ocorre, dizemos que houve uma colisão. Ex:45 % 8 = % 15 = % 8 = % 15 = % 8 = % 15 = 11 O que fazer quando mais de um elemento for inserido na mesma posição de uma tabela hash?

Closed Addressing No endereçamento fechado, a posição de inserção não muda, logo, todos devem ser inseridos na mesma posição, através de uma lista ligada em cada uma % 5 = % 5 = % 5 = 0 colisão com 20 25

Closed Addressing A tabela hash, neste caso, contém um array de listas: class TabelaHash { Lista[] listas; public TabelaHash(int n) { listas = new Lista[n]; for (int i = 0; i < n; i++) listas[i] = new Lista(); } }

Closed Addressing typedef struct No{ int valor; struct No* proximo; } No; typedef struct Lista{ No* head; } Lista; typedef struct TabelaHash{ unsigned int tamanho; Lista** listas; } TabelaHash;

Closed Addressing TabelaHash* criarTabela (const unsigned int tamanho){ TabelaHash* retorno = (TabelaHash*) malloc (sizeof(TabelaHash)); unsigned int i; retorno->tamanho = tamanho; retorno->listas = (Lista**) malloc (tamanho * sizeof(Lista*)); for(i = 0; i < tamanho; i++) retorno->listas[i] = criarLista(); return retorno; }

Closed Addressing Quando uma chave for inserida, a função hash é aplicada, e ela é acrescentada à lista adequada: int hashCode(int chave) { return...; // função hash } void inserir(int chave) { int i = hashCode(chave); listas[i].inserir(chave); }

Closed Addressing Quando uma chave for inserida, a função hash é aplicada, e ela é acrescentada à lista adequada: int hashCode (const int chave, TabelaHash* tabela) { return...; // função hash } void inserirNaTabela (const int chave, TabelaHash* tabela) { const int i = hashCode (chave, tabela); inserirNaLista(chave, tabela->listas[i]); }

Closed Addressing A busca é feita do mesmo modo: calcula-se o valor da função hash para a chave, e a busca é feita na lista correspondente. Se o tamanho das listas variar muito, a busca pode se tornar ineficiente, pois a busca nas listas é seqüencial:

Closed Addressing Por esta razão, a função hash deve distribuir as chaves entre as posições uniformemente: Se o tamanho da tabela for um número primo, há mais chances de ter uma melhor distribuição.

Open Addressing No endereçamento aberto, quando uma nova chave é mapeada para uma posição já ocupada, uma nova posição é indicada para esta chave. Com linear probing, a nova posição é incrementada até que uma posição vazia seja encontrada: ? 27 % 8 =

Open Addressing A tabela hash, neste caso, contém um array de objetos, e posições vazias são indicadas por null. Neste caso, os objetos serão do tipo Integer: class TabelaHash { Integer[] posicoes; public TabelaHash(int n) { posicoes = new Integer[n]; } }

Open Addressing typedef struct TabelaHash{ unsigned int tamanho; int** posicoes; } TabelaHash;

Open Addressing TabelaHash* criarTabela(const unsigned int tamanho){ TabelaHash* retorno = (TabelaHash*) malloc (sizeof(TabelaHash)); unsigned int i; retorno->tamanho = tamanho; retorno->posicoes = (int**) malloc (tamanho* sizeof(int*)); for(i = 0; i < tamanho; ++i) retorno->posicoes[i] = NULL; return retorno; }

Open Addressing: Linear Probing Na inserção, a função hash é calculada, e a posição incrementada, até que uma posição esteja livre: void inserir(int chave) { int i = hashCode(chave); while (posicoes[i] != null) i = (i + 1) % posicoes.length; posicoes[i] = new Integer(chave); }

Open Addressing: Linear Probing void inserirNaTabela(const int chave, TabelaHash* tabela) { int i = hashCode (chave,tabela); while (tabela->posicoes[i] != NULL) i = (i + 1) % tabela->tamanho; tabela->posicoes[i] = (int*) malloc (sizeof(int)); *tabela->posicoes[i] = chave; }

Open Addressing: Linear Probing Valores: 52, 78, 48, 61, 81, 120, 79, 121, 92 Função: hash(k) = k % 13 Tamanho da tabela:

Double Hashing Outra política de endereçamento aberto é o chamado double hashing: ao invés de incrementar a posição de 1, uma função auxiliar é utilizada para calcular o incremento. Esta função também leva em conta o valor da chave ? H(27) = 27 % 8 = Inc(27) = 27*4+7 = 115 ( ) % 8 = 6

Open Addressing: Remoção Para fazer uma busca com endereçamento aberto, basta aplicar a função hash, e a função de incremento até que o elemento ou uma posição vazia sejam encontrados. Porém, quando um elemento é removido, a posição vazia pode ser encontrada antes, o que significaria fim de busca, MESMO que o elemento PERTENÇA à tabela: Inserção do 27 Remoção do 20 Busca pelo ? Não 11 Fim da busca? Sim

Open Addressing: Remoção Para contornar esta situação, mantemos um bit (ou um campo booleano) para indicar que um elemento foi removido daquela posição: X ? Não 11 Fim da busca? Não X 27 Esta posição estaria livre para uma nova inserção, mas não seria tratada como vazia numa busca.

641X11X97 Open Addressing: Expansão Nesta política de hashing, há o que chamamos de fator de carga (load factor). Este fator indica a porcentagem de células da tabela hash que estão ocupadas, incluindo as que foram removidas. Quando este fator fica muito alto (ex: excede 50%), as operações na tabela passam a demorar mais, pois o número de colisões aumenta. 9 ? 1X11X9

Tamanho = 13 Open Addressing: Expansão Quando isto ocorre, é necessário expandir o array que constitui a tabela, e reorganizar os elementos na nova tabela. Como podemos ver, o tamanho atual da tabela passa a ser um parâmetro da função hash. 3440X Tamanho = 7

Open Addressing: Expansão O momento ou critério para expandir a tabela pode variar: Impossibilidade de inserir um elemento Metade da tabela está ocupada O load factor atingiu um valor limite escolhido A terceira opção é a mais comum, pois é um meio termo entre as outras duas.

Quando não usar Hashing? Muitas colisões diminuem muito o tempo de acesso e modificação de uma tabela hash. Para isso é necessário escolher bem: - a função hash - o tratamento de colisões - o tamanho da tabela Quando não for possível definir parâmetros eficientes, pode ser melhor utilizar árvores balanceadas (como AVL), em vez de tabelas hash.

Sara Carvalho da Rocha Brito Tiago Carneiro Pessoa Canto Victor Barbosa de Oliveira Medeiros Vinícius Monteiro de Lira Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto Gomes Pereira Lima Rafael Loureiro de Carvalho