Tabelas de Dispersão (hash tabels)

Documentos relacionados
Módulo 18 - Tabelas de Dispersão. Referências

Módulo 18 - Tabelas de Dispersão

Transformação de Chave. (Hashing)

Transformação de Chave - Hashing

INF 1620 P3-02/07/02 Questão 1 Nome:

INF 1620 P3-29/06/04 Questão 1 Nome:

Estruturas de Dados. Módulo 17 - Busca. 2/6/2005 (c) Dept. Informática - PUC-Rio 1

INF1007: Programação 2 8 Listas Encadeadas. (c) Dept. Informática - PUC-Rio 1

Módulo 10 Listas Encadeadas

Módulo 16 - Ordenação

Computadores Digitais 2. Prof. Rodrigo de Souza Couto

INF 1620 P3-27/11/04 Questão 1 Nome:

INF 1620 P4 11/12/06 Questão 1 Nome:

INF 1620 P2-01/11/03 Questão 1 Nome:

Estruturas de Dados. Módulo 15 - Arquivos. 2/6/2005 (c) Dept. Informática - PUC-Rio 1

Programação de Computadores II. Cap. 16 Ordenação

INF 1620 P3-06/12/03 Questão 1 Nome:

Estruturas de Dados. Módulo 11 Pilhas. 9/8/2005 (c) Dept. Informática - PUC-Rio 1

Instituto de C. Linguagem C: Listas. Luis Martí Instituto de Computação Universidade Federal Fluminense -

Computadores Digitais 2. Prof. Rodrigo de Souza Couto

Estruturas de Dados. Módulo 12 - Filas. 9/8/2005 (c) Dept. Informática - PUC-Rio 1

Tabelas de Dispersão (hash tabels)

INF 1620 P2-23/10/04 Questão 1 Nome:

Instituto de C. Filas. Luis Martí Instituto de Computação Universidade Federal Fluminense -

INF1007 Programação 2 9 Pilhas. (c) Dept. Informática - PUC-Rio 1

Módulo 16 - Ordenação. Referências

Módulo 7 Cadeias de Caracteres

INF P3-23/06/07 Questão 1 Nome:

Programação II. Listas Encadeadas (Linked Lists) Bruno Feijó Dept. de Informática, PUC-Rio

INF 1620 P2-14/10/05 Questão 1 Nome:

Cadeias de Caracteres (Strings)

INF1007: Programação 2. 4 Tipos Estruturados. 10/23/09 (c) Dept. Informática - PUC-Rio 1

Módulo 8 Tipos Estruturados

Departamento de Informática - PUC-Rio INF 1007 Programação 2 P3 23/06/2010

Métodos Computacionais. Listas Encadeadas

Linguagem C: Ordenação

INF 1620 P4 30/06/07 Questão 1 Nome:

INF 1620 P3-25/11/05 Questão 1 Nome:

Listas Ligadas (Encadeadas) Listas Simplesmente Encadeadas

Módulo 5 Vetores e Alocação Dinâmica

REVISÃO DE C. Vanessa Braganholo Estruturas de Dados e Seus Algoritmos

INF 1620 P4-27/06/02 Questão 1 Nome:

Departamento de Informática - PUC-Rio INF 1007 Programação 2 P3 26/11/2010

ÁRVORES ABB (ÁRVORES BINÁRIAS DE BUSCAS) Sérgio Carlos Portari Júnior

Programação de Computadores II. Cap. 7 Cadeias de Caracteres

INF 1007 Programação II

INF1007: Programação 2 6 Ordenação de Vetores. 01/10/2015 (c) Dept. Informática - PUC-Rio 1

INF 1007 Programação II

Estruturas de Dados Aula 16: Árvores com Número Variável 13/06/2011

Departamento de Informática PUC-Rio INF Estruturas de Dados Lista 2 Completa (Gerada em 8 de maio de 2006)

INF 1620 P4-06/12/02 Questão 1 Nome:

Estruturas de Dados Aula 12: Outras Implementações de Listas 18/04/2011

Aluno: Valor Nota Q1 3.0 Q2 2.5 Q3 2.5 Q4 2.0 Total 10.0

INF 1620 P4-01/07/08 Questão 1 Nome:

Fontes Bibliográficas. Listas Circulares. Função Imprime

Fundamentos de Programação 1

Programação de Computadores II. Cap. 17 Busca

INF 1620 P4-09/07/03 Questão 1 Nome:

INF1007: Programação 2. 0 Revisão. 06/08/2015 (c) Dept. de Informática - PUC-Rio 1

INF 1620 P4-13/12/01 Questão 1 Nome:

P3 Programação II Departamento de Informática/PUC-Rio 27 de junho de 2013

EPs 1 e 2. EP2: veja. EP1: veja

Fontes Bibliográficas. Estruturas de Dados Aula 15: Árvores. Livros:

INF1005: Programação 1. Vetores. 02/05/10 (c) Paula Rodrigues 1

INF P4-12/12/09 Questão 1 Nome:

PRIMEIRA AVALIAÇÃO IDENTIFICAÇÃO. Nome: 22/09/2010

Estruturas de Dados. Módulo 4 Funções. 9/8/2005 (c) Dept. Informática - PUC-Rio 1

Listas Lineares. Livro Projeto de Algoritmos Nívio Ziviani Capítulo 3 Seção 3.1

INF1007: Programação 2 7 Busca em Vetores. 01/04/2014 (c) Dept. Informática - PUC-Rio 1

ESTRUTURA DE DADOS E ALGORITMOS. Hashing (Tabela de Dispersão) Cristina Boeres

Métodos Computacionais. Tipos Estruturados

INF 1620 P3-21/06/08 Questão 1 Nome:

Estruturas de Dados Aula 17: Estruturas Genéricas 15/06/2011

Programação de Computadores II. Cap. 7 Cadeias de Caracteres 1/2

Estruturas de Dados Filas

INF1007: Programação 2. 2 Alocação Dinâmica. 17/02/2014 (c) Dept. Informática - PUC-Rio 1

Árvores. Prof. César Melo DCC/ICE/UFAM

Listas Encadeadas. Fabrício J. Barth. BandTec - Faculdade de Tecnologia Bandeirantes

TABELAS HASH. Vanessa Braganholo Estruturas de Dados e Seus Algoritmos

Capítulo 6: Arquivos

Árvores. Prof. César Melo DCC/ICE/UFAM

i a[i]

ESTRUTURAS COMPOSTAS

INF 1007 Programação II

INF1007: Programação 2 9 Tipos Abstratos de Dados. (c) Dept. Informática - PUC-Rio 1

Caracteres e Cadeias de Caracteres

max1: 20,max2:+ max1:15, max2:20 max1:30,max2:32,max3:35 max1:40,max2:+

Programação II. Ordenação (sort) Bruno Feijó Dept. de Informática, PUC-Rio

ESTRUTURAS COMPOSTAS VETOR

P2 Programação II Departamento de Informática/PUC-Rio

INF 1620 P2-17/05/08 Questão 1 Nome:

Referências. Arquivos. Tópicos Principais. Programação de Computadores II. Motivação. Motivação. Abertura de arquivo. Slides da profa.

Estruturas da linguagem C. 1. Identificadores, tipos primitivos, variáveis e constantes, operadores e expressões.

Módulo 14 - Estruturas genéricas

Cap. 3 Entrada e Saída e Controle de Fluxo

Introdução a Programação. Listas Encadeadas

Alocação de Memória. Lucas Ferrari de Oliveira Professor Adjunto Universidade Federal do Paraná (UFPR)

12. Filas Interface do tipo fila

Transcrição:

INF1010-3WB Estruturas de Dados Avançadas Tabelas de Dispersão (hash tabels) 13/05/2018 2010 DI, PUC-Rio Estruturas de Dados Avançadas 2010.1 1

Motivação Busca (acesso) com vetor é muito eficiente Info* v[n];... v[i]->... Informação 0 Informação 2 Informação 1 Informação 3 Informação (n-1) 13/05/2018 (c) Dept. Informática - PUC-Rio 2

Nem sempre temos chaves numéricas pequenas struct Aluno { int mat; char nome[81]; char email[41]; char turma; ; Como fazer para buscar pelo nome ou pela matrícula? 13/05/2018 (c) Dept. Informática - PUC-Rio 3

Idéia dos escaninhos A primeira letra do nome define a caixa onde a informação é depositada Hash : Info [0, N] x h( x) 13/05/2018 (c) Dept. Informática - PUC-Rio 4

Tabelas de Dispersão (Hash Tables) utilizadas para buscar um elemento em ordem constante O(1) necessitam de mais memória, proporcional ao número de elementos armazenado ex.: {14,16,58,39,44,10,72,22, chave k Î [0,99] 8 elementos Þ N=13 kî[0,99] h h: [0,99] [0,12] h(k) = (k % 13) 0 1 2 3 4 5 6 7 8 9 10 11 12 39 14-16 - 44 58 72-22 10 - - 13/05/2018 (c) Dept. Informática - PUC-Rio 5

Tabelas de Dispersão (Hash Tables) utilizadas para buscar um elemento em ordem constante O(1) necessitam de mais memória, proporcional ao número de elementos armazenado ex.: {14,16,58,39,44,10,72,22, chave k Î [0,99] 8 elementos Þ N=20 kî[0,99] h h(k) = (k % 20) h: [0,99] [0,12] 13/05/2018 (c) Dept. Informática - PUC-Rio 6 0 1 2 22 3 4 5 6 7 8 9 10 11 12 13 14 14,44 15 16 16 17 18 58 19 39

Função de dispersão (função de hash) mapeia uma chave de busca em um índice da tabela deve apresentar as seguintes propriedades: ser eficientemente avaliada (para acesso rápido) espalhar bem as chaves de busca (para minimizarmos colisões) colisão = duas ou mais chaves de busca são mapeadas para um mesmo índice da tabela de hash kî[0,99] h h: [0,99] [0,12] h(k) = (k % 13) 13/05/2018 (c) Dept. Informática - PUC-Rio 7

Dimensão da tabela deve ser escolhida para diminuir o número de colisões costuma ser um valor primo a taxa de ocupação não deve ser muito alta: a taxa de ocupação não deve ser superior a 75% uma taxa de 50% em geral traz bons resultados uma taxa menor que 25% pode representar um gasto excessivo de memória Fator de carga = (#entradas/tamanho) 13/05/2018 (c) Dept. Informática - PUC-Rio 8

Exemplo de Tabelas de Dispersão tipo Aluno: define o tipo da estrutura de dados de interesse tipo Hash: define o tipo dos vetores de ponteiros para Aluno struct Aluno { int mat; char nome[81]; char email[41]; char turma; ; int hash (int mat) { return (mat%n); #define N 127 typedef Aluno* Hash[N]; 13/05/2018 (c) Dept. Informática - PUC-Rio 9

Estratégias para tratamento de colisão uso da primeira posição consecutiva livre(encadeamento interior): simples de implementar tende a concentrar os lugares ocupados na tabela uso de uma segunda função de dispersão (encadeamento aberto): evita a concentração de posições ocupadas na tabela usa uma segunda função de dispersão para re-posicionar o elemento uso de listas encadeadas(encadeamento exterior): simples de implementar cada elemento da tabela hash representa um ponteiro para uma lista encadeada 13/05/2018 (c) Dept. Informática - PUC-Rio 10

Tratamento de Colisão Uso da posição consecutiva livre: estratégia geral: armazene os elementos que colidem em outros índices, ainda não ocupados, da própria tabela estratégias particulares: diferem na escolha da posição ainda não ocupada para armazenar um elemento que colide 13/05/2018 (c) Dept. Informática - PUC-Rio 11

Uso da posição consecutiva livre Estratégia 1: se a função de dispersão mapeia a chave de busca para um índice já ocupado, procure o próximo índice livre da tabela (usando incremento circular) para armazenar o novo elemento x h(x) busca posição livre 13/05/2018 (c) Dept. Informática - PUC-Rio 12

Operação de busca suponha que uma chave x for mapeada pela função de hash h para um determinado índice h(x) procure a ocorrência do elemento a partir de h(x), até que o elemento seja encontrado ou que uma posição vazia seja encontrada 13/05/2018 (c) Dept. Informática - PUC-Rio 13

Operação de busca entrada: a tabela e a chave de busca saída: o ponteiro do elemento, se encontrado NULL, se o elemento não for encontrado Aluno* hsh_busca (Hash tab, int mat) { int h = hash(mat); while (tab[h]!= NULL) { if (tab[h]->mat == mat) return tab[h]; h = (h+1) % N; return NULL; 13/05/2018 (c) Dept. Informática - PUC-Rio 14

Operação de inserção e modificação suponha que uma chave x for mapeada pela função de hash h para um determinado índice h(x) procure a ocorrência do elemento a partir de h(x), até que o elemento seja encontrado ou que uma posição vazia seja encontrada se o elemento existir, modifique o seu conteúdo se não existir, insira um novo na primeira posição livre que encontrar na tabela, a partir do índice mapeado 13/05/2018 (c) Dept. Informática - PUC-Rio 15

Inserção/modificação Aluno* hsh_insere(hash tab,int mat, char* n, char* e, char t) { int h = hash(mat); while (tab[h]!= NULL) { if (tab[h]->mat == mat) break; h = (h+1) % N; if (tab[h]==null) { /* não encontrou o elemento */ tab[h] = (Aluno*) malloc(sizeof(aluno)); tab[h]->mat = mat; /* atribui/modifica informação */ strcpy(tab[h]->nome,n); strcpy(tab[h]->email,e); tab[h]->turma = t; return tab[h]; 13/05/2018 (c) Dept. Informática - PUC-Rio 16

Tratamento de Colisão Uso de uma segunda função de dispersão: exemplo: primeira função de hash: segunda função de hash: h ( x) = x% N h' ( x) = N - 2 - x%( N - 2) onde x representa a chave de busca e N a dimensão da tabela se houver colisão, procure uma posição livre na tabela com incrementos dados por h (x) em lugar de tentar (h(x)+1)%n, tente (h(x)+h (x))%n 13/05/2018 (c) Dept. Informática - PUC-Rio 17

Uso de uma segunda função de dispersão (cont) cuidados na escolha da segunda função de dispersão: nunca pode retornar zero pois isso não faria com que o índice fosse incrementado não deve retornar um número divisor da dimensão da tabela pois isso limitaria a procura de uma posição livre a um sub-conjunto restrito dos índices da tabela se a dimensão da tabela for um número primo, garante-se automaticamente que o resultado da função não será um divisor 13/05/2018 (c) Dept. Informática - PUC-Rio 18

Busca com segunda função de colisão static int hash2 (int mat) { return N - 2 - mat%(n-2); Aluno* hsh_busca (Hash tab, int mat) { int h = hash(mat); int h2 = hash2(mat); while (tab[h]!= NULL) { if (tab[h]->mat == mat) return tab[h]; h = (h+h2) % N; return NULL; 13/05/2018 (c) Dept. Informática - PUC-Rio 19

Tratamento de Colisão Uso de listas encadeadas cada elemento da tabela hash representa um ponteiro para uma lista encadeada todos os elementos mapeados para um mesmo índice são armazenados na lista encadeada os índices da tabela que não têm elementos associados representam listas vazias x h(x) 13/05/2018 (c) Dept. Informática - PUC-Rio 20

Tratamento de Colisão Exemplo: cada elemento armazenado na tabela será um elemento de uma lista encadeada a estrutura da informação deve prever um ponteiro adicional para o próximo elemento da lista struct aluno { int mat; char nome[81]; char turma; char email[41]; struct aluno* prox; /* encadeamento na lista de colisão */ ; typedef struct aluno Aluno; 13/05/2018 (c) Dept. Informática - PUC-Rio 21

/* função para inserir ou modificar um determinado elemento */ Aluno* hsh_insere (Hash tab, int mat, char* n, char* e, char t) { int h = hash(mat); Aluno* a = tab[h]; while (a!= NULL) { if (a->mat == mat) break; a = a->prox; if (a==null) { /* não encontrou o elemento */ /* insere novo elemento no início da lista */ a = (Aluno*) malloc(sizeof(aluno)); a->mat = mat; a->prox = tab[h]; tab[h] = a; /* atribui ou modifica informação */ strcpy(a->nome,n); strcpy(a->email,e); a->turma = t; return a; 13/05/2018 (c) Dept. Informática - PUC-Rio 22

Exemplo: número de ocorrências de palavras Especificação: programa para exibir quantas vezes cada palavra ocorre em um dado texto entrada: um texto T saída: uma lista de palavras, em ordem decrescente do número de vezes que cada palavra ocorre em T observações: uma palavra é uma seqüência de uma ou mais letras (maiúsculas ou minúsculas) por simplicidade, caracteres acentuados não são considerados 13/05/2018 (c) Dept. Informática - PUC-Rio 23

Exemplo: número de ocorrências de palavras Armazenamento das palavras lidas e da sua freqüência: tabela de dispersão usa a própria palavra como chave de busca Função para obter a freqüência das palavras: dada uma palavra, tente encontrá-la na tabela se não existir, armazene a palavra na tabela se existir, incremente o número de ocorrências da palavra Função para exibir as ocorrências em ordem decrescente: crie um vetor armazenando as palavras da tabela de dispersão ordene o vetor exiba o conteúdo do vetor 13/05/2018 (c) Dept. Informática - PUC-Rio 24

Exemplo: número de ocorrências de palavras Tabela de dispersão: usa a lista encadeada para o tratamento de colisões #define NPAL 64 /* dimensão máxima de cada palavra */ #define NTAB 127 /* dimensão da tabela de dispersão */ /* tipo que representa cada palavra */ struct palavra { char pal[npal]; int n; /* contador de ocorrências */ struct palavra* prox; /* colisão com listas */ ; typedef struct palavra Palavra; /* tipo que representa a tabela de dispersão */ typedef Palavra* Hash[NTAB]; 13/05/2018 (c) Dept. Informática - PUC-Rio 25

Exemplo: número de ocorrências de palavras Leitura de palavras: captura a próxima seqüência de letras do arquivo texto entrada: ponteiro para o arquivo de entrada cadeia de caracteres armazenando a palavra capturada saída: inteiro, indicando leitura bem sucedida (1) ou não (0) processamento: capture uma palavra, pulando os caracteres que não são letras e armazenando a seqüência de letras a partir da posição do cursor do arquivo para identificar se um caractere é letra ou não, use a função isalpha disponibilizada pela interface ctype.h 13/05/2018 (c) Dept. Informática - PUC-Rio 26

static int le_palavra (FILE* fp, char* s) { int i = 0; int c; /* pula caracteres que não são letras */ while ((c = fgetc(fp))!= EOF) { if (isalpha(c)) break; if (c == EOF) return 0; else s[i++] = c /* primeira letra já foi capturada */ /* lê os próximos caracteres que são letras */ while ( i<npal-1 && (c = fgetc(fp))!= EOF && isalpha(c)) s[i++] = c; s[i] = '\0'; return 1; 13/05/2018 (c) Dept. Informática - PUC-Rio 27

Exemplo: número de ocorrências de palavras Função para inicializar a tabela: atribui NULL a cada elemento static void inicializa (Hash tab) { int i; for (i=0; i<ntab; i++) tab[i] = NULL; 13/05/2018 (c) Dept. Informática - PUC-Rio 28

Exemplo: número de ocorrências de palavras Função de dispersão: mapeia a chave de busca (uma cadeia de caracteres) em um índice da tabela soma os códigos dos caracteres que compõem a cadeia e tira o módulo dessa soma para se obter o índice da tabela static int hash (char* s) { int i; int total = 0; for (i=0; s[i]!='\0'; i++) total += s[i]; return total % NTAB; 13/05/2018 (c) Dept. Informática - PUC-Rio 29

Exemplo: número de ocorrências de palavras Função para acessar os elementos na tabela: entrada: uma palavra (chave de busca) saída: o ponteiro da estrutura Palavra associada processamento: se a palavra ainda não existir na tabela, crie uma nova palavra e forneça como retorno essa nova palavra criada 13/05/2018 (c) Dept. Informática - PUC-Rio 30

static Palavra *acessa (Hash tab, char* s) { Palavra* p; int h = hash(s); for (p=tab[h]; p!=null; p=p->prox) { if (strcmp(p->pal,s) == 0) return p; /* insere nova palavra no inicio da lista */ p = (Palavra*) malloc(sizeof(palavra)); strcpy(p->pal,s); p->n = 0; p->prox = tab[h]; tab[h] = p; return p; 13/05/2018 (c) Dept. Informática - PUC-Rio 31

Exemplo: número de ocorrências de palavras Trecho da função principal: acessa cada palavra incrementa o seu número de ocorrências... inicializa(tab); while (le_palavra(fp,s)) { Palavra* p = acessa(tab,s); p->n++;... 13/05/2018 (c) Dept. Informática - PUC-Rio 32

Exemplo: número de ocorrências de palavras Exibição do resultado ordenado: crie dinamicamente um vetor para armazenar as palavras vetor de ponteiros para a estrutura Palavra tamanho do vetor = número de palavras armazenadas na tabela coloque o vetor em ordem decrescente do número de ocorrências de cada palavra se duas palavras tiverem o mesmo número de ocorrências, use a ordem alfabética como critério de desempate 13/05/2018 (c) Dept. Informática - PUC-Rio 33

/* função para percorrer a tabela e contar o número de palavras entrada: tabela de dispersão */ static int conta_elems (Hash tab) { int i; Palavra* p; int total = 0; for (i=0; i<ntab; i++) { for (p=tab[i]; p!=null; p=p->prox) total++; return total; 13/05/2018 (c) Dept. Informática - PUC-Rio 34

/* função para criar dinamicamente o vetor de ponteiros entrada: número de elementos tabela de dispersão */ static Palavra** cria_vetor (int n, Hash tab) { int i, j=0; Palavra* p; Palavra** vet = (Palavra**) malloc(n*sizeof(palavra*)); /* percorre tabela preenchendo vetor */ for (i=0; i<ntab; i++) { for (p=tab[i]; p!=null; p=p->prox) vet[j++] = p; return vet; 13/05/2018 (c) Dept. Informática - PUC-Rio 35

Exemplo: número de ocorrências de palavras Ordenação do vetor (de ponteiros para Palavra): utilize a função qsort da biblioteca padrão defina a função de comparação apropriadamente static int compara (const void* v1, const void* v2) { Palavra** p1 = (Palavra**)v1; Palavra** p2 = (Palavra**)v2; if ((*p1)->n > (*p2)->n) return -1; else if ((*p1)->n < (*p2)->n) return 1; else return strcmp((*p1)->pal,(*p2)->pal); 13/05/2018 (c) Dept. Informática - PUC-Rio 36

Exemplo: número de ocorrências de palavras Impressão da tabela: static void imprime (Hash tab) { int i; int n; Palavra** vet; /* cria e ordena vetor */ n = conta_elems(tab); vet = cria_vetor(n,tab); qsort(vet,n,sizeof(palavra*),compara); /* imprime ocorrências */ for (i=0; i<n; i++) printf("%s = %d\n",vet[i]->pal,vet[i]->n); /* libera vetor */ free(vet); 13/05/2018 (c) Dept. Informática - PUC-Rio 37

Exemplo: número de ocorrências de palavras Função Principal: #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h>... /* funções auxiliares mostradas acima */ 13/05/2018 (c) Dept. Informática - PUC-Rio 38

int main (int argc, char** argv) { FILE* fp; Hash tab; char s[npal]; if (argc!= 2) { printf("arquivo de entrada nao fornecido.\n"); return 0; /* abre arquivo para leitura */ fp = fopen(argv[1],"rt"); if (fp == NULL) { printf("erro na abertura do arquivo.\n"); return 0; /* conta ocorrência das palavras */ inicializa(tab); while (le_palavra(fp,s)) { Palavra* p = acessa(tab,s); p->n++; /* imprime ordenado */ imprime (tab); return 0; 13/05/2018 (c) Dept. Informática - PUC-Rio 39

Resumo Tabelas de dispersão (hash tables): utilizadas para buscar um elemento em ordem constante O(1) Função de dispersão (função de hash): mapeia uma chave de busca em um índice da tabela Estratégias para tratamento de colisão: uso da primeira posição consecutiva livre uso de uma segunda função de dispersão uso de listas encadeadas k h h(k) 0 1 N 39 14-16 - 44 58 13/05/2018 (c) Dept. Informática - PUC-Rio 40

Referências Waldemar Celes, Renato Cerqueira, José Lucas Rangel, Introdução a Estruturas de Dados, Editora Campus (2004) Capítulo 18 Tabelas de dispersão 13/05/2018 (c) Dept. Informática - PUC-Rio 41