Buscar

sequencial, binária e tabelas hash

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 3 páginas

Prévia do material em texto

Métodos de pesquisa em listas: sequencial, binária e tabelas hash
A tabela hash é uma estrutura de dados muito eficiente, que associa chaves de pesquisa a valores. A partir de uma chave simples, é possível fazer a inserção, a busca e a atualização de dados em complexidade de tempo constante, ou seja, O(1), no caso médio.
O principal desafio está na escolha da função hash, pois se for feita de forma imprecisa, acarretará um desempenho linear, ou seja, O(K), devido a colisões em suas linhas. Dessa forma, a escolha da função hash é o ponto-chave para o desempenho da tabela hash.
1. 
A busca sequencial é uma técnica simples e intuitiva para buscar elementos em vetores ou listas.
Tendo a informação de que os dados estão ordenados de forma crescente,​​​​​​​ qual otimização você pode aplicar na busca sequencial?
D. Parar a execução e informar que o valor não existe, quando o valor atual for maior que o buscado.
O desempenho de pior caso da busca sequencial pode ser otimizado sabendo-se que o vetor está ordenado. Para tanto, continua-se a buscar um elemento enquanto o elemento atual for maior que o buscado. No momento em que ele for menor, sabe-se que o vetor é ordenado e, no futuro, não será possível encontrar outro elemento maior. O contrário não é verdade, pois, caso seja encontrado um valor menor que o buscado, ainda é possível achar valores maiores no futuro. Funções hash podem ser utilizadas apenas em tabelas hash. Ainda, descobrir a posição de um elemento sem buscar em várias posições do vetor também só é possível em tabelas hash.
2. 
A busca binária é uma técnica eficiente para buscar elementos em vetores ou listas. A única restrição desse método é que o vetor ou a lista estejam ordenados.
Das seguintes sequências de acessos em um vetor, qual é válida em uma execução de busca binária?​​​​​​​
C. 5, 2, 1.
Em cada iteração da busca binária, o elemento do meio do intervalo atual é acessado. Nesse sentido, para acessar a posição 1, é necessário que o tamanho do intervalo seja 2. Assumindo que o vetor tivesse tamanho 2, não seria possível nas alternativas (1, 2, 5) e (1, 5, 2) acessar elementos maiores que 2 após esse primeiro acesso. No caso da alternativa (5, 7, 3), o problema vai quando o elemento 5 é acessado e logo todos os menores que 5 são ignorados, mas, logo após, o número 3 é acessado. O mesmo ocorre na alternativa (5, 2, 8). Portanto, a alternativa correta é (5, 2, 1), um vetor de tamanho 10; o primeiro acesso é o 5, após a metade é o 2 e, por fim, o 1.
3. Tabelas hash são estruturas muito eficientes utilizadas por diversas linguagens de programação e serviços. Entender seu funcionamento é crucial para o desenvolvedor, o qual deverá decidir o tamanho da tabela e a função hash que otimiza o desempenho de determinada aplicação.
Considere uma tabela hash de 5 posições (de 1 a 5, aceitando repetições) e uma função hash que representa a i-ésima letra do alfabeto com o número i. Quantas colisões ocorrem após a inserção das chaves: A, B, A, C, A, E​​​​​​​?
B. 2.
Uma tabela hash de 5 posições tem índices de 1 a 5. A função hash converte um caractere para um índice de acordo com a ordem no alfabeto. Por exemplo, a letra A é 1, a letra B é 2, e assim por diante. Nesse sentido, colisões vão ocorrer apenas quando a mesma letra for inserida. Como foi inserida três vezes a letra A, e as colisões ocorrem a partir da segunda inserção, o total de colisões é 2: a segunda inserção da letra A e a terceira.
4. 
Métodos de busca são muito utilizados em milhares de sistemas e aplicações reais. O projetista e o desenvolvedor devem ter muito conhecimento sobre seu funcionamento e também sobre as vantagens e desvantagens de cada método.
Para uma aplicação que realiza muitas inserções e atualizações nos dados, qual é o método mais indicado?​​​​​​​
D. Tabela hash implementada com vetores e listas para tratar colisões.
A busca sequencial tem um custo muito alto e só é indicada para aplicações com vetores pequenos que realizam poucas buscas. A binária, por outro lado, pode ser eficiente, dependendo do caso: inserir dados sempre ordenados aumenta o custo da inserção, que, no caso de aplicação com muitas inserções e atualizações nos dados, é um ponto importante; ordenar apenas quando atualizar vai aumentar o custo das atualizações, que também são muito recorrentes nesse caso. Já uma lista encadeada não permite encontrar os elementos de forma veloz, pois é necessário percorrê-la do início ao fim. Assim, a resposta correta é tabela hash, pois, dada uma chave, é possível inserir e atualizar apenas computando a função hash, que tem baixo custo.
5. 
Uma das maneiras de avaliar o melhor método para uma aplicação é analisar a complexidade de pior e melhor caso dos métodos e constatar com as entradas da aplicação-alvo. Para tanto, é necessário conhecimento sobre ordens assintóticas.
Nesse sentido, qual é a complexidade de pior caso das buscas sequencial, binária e na tabela hash, respectivamente?​​​​​​​
C. O(n), O(log2 n), O(K).
Para calcular a complexidade de pior caso, deve-se pensar na pior entrada possível para o programa. No caso da busca sequencial, como se tem um laço que vai de 1 até N, o pior caso é percorrer esse laço N vezes. Nesse sentido, a complexidade da busca sequencial é O(n). Quando se fala da busca binária, ela é mais eficiente, pois a cada iteração elimina metade do intervalo. Essa eliminação de metade do vetor por vez remete a uma árvore binária, por isso o nome da busca. Nesse caso, a complexidade de tempo é O(log2 n). Por fim, a tabela hash tem uma complexidade de melhor caso de O(1); entretanto, no pior caso, podem ocorrer K colisões, e uma lista encadeada será percorrida até o K-ésimo elemento. Logo, complexidade O(K).
Desafio
As colisões ocorrem quando mais de uma chave é mapeada para a mesma posição da tabela. Quando isso acontece, uma busca sequencial naquela posição é necessária para encontrar uma chave. Se isso acontecer muitas vezes, o desempenho de uma aplicação ou sistema pode ser reduzido em até centenas de vezes.
Qual função hash você utilizaria, buscando diminuir o número de colisões ocorridas? Exemplifique.
O defeito da função hash utilizada originalmente é que ela retorna sempre o primeiro caractere do nome da pessoa. Fazendo isso, sempre que os nomes começarem com a mesma letra, diversas colisões irão ocorrer. Uma função hash mais eficiente seria uma que, utilizando multiplicação por números primos, utilizasse todos os caracteres da string e não só o primeiro.
Por exemplo:
def funcao_hash(chave, tamanho_tabela):
 valor = 5381
 for caractere in chave:
 valor = 33 * valor + ord(caractere)
 valor = valor % tamanho_tabela
 return valor
print(funcao_hash("João", 1024))
print(funcao_hash("Maria", 1024))

Outros materiais