2. Pesquisa em Memória
Primária
Universidade Federal de Goiás
Programa de Pós-Graduação em Ciência da Computação
Disciplina: Estrutura de Dados e Projeto de Algoritmos
Professora: Telma Woerel Lima Soares
Mestrandos:
Carlos Moura - Flávio Vilela - Norton Guimarães
3. Agenda
• 5 – Pesquisa em Memória Primária
• 5.1 - Pesquisa Sequencial
• 5.2 - Pesquisa Binária
• 5.3 - Árvores de Pesquisa
• 5.3.1 - Árvores Binárias de Pesquisa Sem Balanceamento
• 5.3.2 - Árvores Binárias de Pesquisa Com Balanceamento
4. 5 - Pesquisa em Memória Primária
• Recuperar informação a partir de grande massa de informações armazenadas.
• Informação divida em registro.
• Cada registro possui uma chave.
• O objetivo é encontrar um ou mais registros com a mesma chave.
• Pesquisa com sucesso.
• Pesquisa sem sucesso.
• Tabela ou arquivo
5. Qual método escolher?
• A escolha depende de vários aspectos:
• Quantidade de dados envolvidos.
• Arquivo sujeito a várias retiradas e inserções freqüentes.
• Conteúdo do arquivo estável.
6. Operações comuns
• Considerar os algoritmos de pesquisa como tipos abstratos de dados.
• Operações comuns
• Inicializar a estrutura.
• Pesquisar.
• Inserir.
• Retirar.
• Ordenar um arquivo e obter registros de acordo com a chave.
• Unir dois arquivos.
• Dicionário
7. 5.1 - Pesquisa seqüencial
• É o método mais simples que existe.
• Pesquisar seqüencialmente o registro, até encontrar a chave desejada.
• Armazenamento de dados em arranjo, onde cada registro possui uma chave.
• Uso de registro sentinela.
9. Análise
• Melhor caso: C(n) = 1;
• Pior caso: C(n) = n;
• Caso médio: C(n) = (n + 1) / 2;
• Caso sem sucesso: C(n) = n + 1;
10. 5.2 - Pesquisa binária
• Mais eficiente se os registros forem mantidos em ordem.
• Verificar se a chave está presente
• Compare a chave com o registro do meio.
• Se chave menor
• A chave procurada está do lado esquerdo
• Se chave maior
• A chave procurada está do lado direito
• Repita até encontrar a chave ou até ficar apenas uma chave diferente da procurada.
12. Análise
• A cada iteração, o tamanho da tabela é dividido ao meio.
• Logo, o número de vezes que o tamanho da tabela é dividido ao meio é cerca
de log n.
• Não deve ser usado em aplicações muito dinâmicas.
13. 5.3 - Árvores de Pesquisa
• A árvore de pesquisa é uma estrutura de dados muito eficiente para
armazenar informação.
• Particularmente adequada quando existe necessidade de considerar todos ou
alguma combinação de:
1. Acesso direto e sequencial eficientes.
2. Facilidade de inserção e retirada de registros.
3. Boa taxa de utilização de memória.
4. Utilização de memória primária e secundária.
14. 5.3.1 Árvores Binárias de Pesquisa Sem
Balanceamento
• Para qualquer nó que contenha um registro
• Temos a relação invariante
1. Todos os registros com chaves menores estão na subárvore à esquerda.
2. Todos os registros com chaves maiores estão na subárvore à direita.
15. Árvore Binária de Pesquisa
• O nível do nó raiz é 0.
• Se um nó está no nível i então a raiz de
suas subárvores estão no nível i + 1.
• A altura de um nó é o comprimento do
caminho mais longo deste nó até um nó
folha. O exemplo tem altura 4.
• Uma árvore é dita binária se tem 0 à 2 nós
folha.
16. Procedimento para pesquisa na árvore
• Compare-a com a chave que está na raiz.
• Se x é menor, vá para a subárvore
esquerda.
• Se x é maior, vá para a subárvore direita.
• Repita o processo recursivamente, até
que a chave procurada seja encontrada
ou um nó folha é atingido.
• Se a pesquisa tiver sucesso o conteúdo
retorna no próprio registro x.
17. Procedimento para inserir na árvore
Árvores Binárias de Busca
4
2 7
1 5 83
EXEMPLO:
Para inserir a chave 6 na árvore ao lado. O nó corrente é a raiz.
• 6 é maior que 4. Inserir na subárvore direita.
• 6 é menor que 7. Inserir na subárvore da esquerda.
• 6 é maior que 5. Inserir na subárvore da direita.
• A subárvore está vazia. 6 deve ser a raiz desta.
6
18. Procedimento para retirar X da árvore
• A retirada de um registro não é tão simples quanto a inserção.
• Se o nó que contém o registro a ser retirado possui no máximo um
descendente) a operação é simples.
• No caso do nó conter dois descendentes o registro a ser retirado deve ser
primeiro:
• substituído pelo registro mais à direita na subárvore esquerda;
• ou pelo registro mais à esquerda na subárvore direita.
19. Exemplo de retirar X da árvore
EX.: Remover o nó que contém a chave 6 da árvore abaixo:
4
2 6
1 73
4
2 7
1 3
20. Exemplo de retirar X da árvore
EX.: Remover o nó que contém a chave 4 da árvore abaixo:
4
2 6
1 5 73
3
2 6
1 5 7
21. Caminhar na árvore
• Considerando que o percurso na árvore comece pela raiz, desça pela sua
esquerda (e pela esquerda de cada nó), até chegar novamente à raiz, agora
pela direita, podemos caracterizar cada um dos três percursos como:
• Pre-order;
• In-order;
• Pos-order.
22. Exemplo de Caminhar na árvore
a
b c
EXEMPLO:
Listagem dos nós da árvore ao lado, nos três percursos:
- PRE-ORDER (ou pré-ordem): a b c
- IN-ORDER (ou simétrica): b a c
- POS-ORDER (ou pós-ordem): b c a
23. Análise
• O número de comparações em uma pesquisa com sucesso:
• melhor caso : C(n) = O(1)
• pior caso : C(n) = O(n)
• caso médio : C(n) = O(log n)
• O tempo de execução dos algoritmos para árvores binárias de pesquisa dependem
muito do formato das árvores.
• Para obter o pior caso basta que as chaves sejam inseridas em ordem crescente ou
decrescente. Neste caso a árvore resultante é uma lista linear, cujo número médio de
comparações é (n + 1)/2.
24. Árvore completamente balanceada
• Nós folha (externos) aparecem em no máximo dois níveis
adjacentes
• Minimiza o tempo médio de pesquisa assumindo distribuição uniforme
das chaves.
• Problema: manter árvore completamente balanceada após cada
inserção é muito caro.
25. Árvore completamente balanceada
• Para inserir a chave 1 na árvore do exemplo à esquerda e obter a árvore à
direita do mesmo exemplo é necessário movimentar todos os nós da árvore
original
26. Árvores “quase balanceadas”
• Solução intermediária que mantém a árvore “quase balanceada”, em vez de tentar manter a
árvore completamente balanceada.
• Oferece bons tempos de pesquisa, próximos ao tempo ótimo da arvore completamente
balanceada, com um custo menor para manter o balanceamento.
• Exemplos de restrições aplicadas a árvores para fazê-las “quase balanceadas”
• Fazer que todas as folhas aparecem no mesmo nível
• Restringir a diferença entre as alturas das subárvores de cada nó
• Minimizar o comprimento do caminho interno da árvore
• Exemplos: AVL, RUBRO-NEGRAS, SBB
27. Árvores SBB
(Symmetric Binary B-trees)
• Uma árvore SBB é uma árvore binária com apontadores
verticais e horizontais, tal que:
• Todos os caminhos da raiz até cada nó externo possuem o
mesmo número de apontadores verticais.
• Não podem existir dois apontadores horizontais sucessivos.
29. Árvores SBB
Estrutura e dicionário
• Diferenças da árvore sem balanceamento:
• constantes Horizontal e Vertical : representam as inclinações das
referências às subárvores;
• campo propSBB: utilizado para verificar quando a propriedade SBB
deixa de ser satisfeita
• campos incE e incD: indicam o tipo de referência (horizontal ou vertical)
que sai do nó.
31. • Pesquisa
• Procedimento de pesquisa das árvores SBB é idêntico ao procedimento
para árvores sem balanceamento. Os campos BitE e BitD são ignorados;
• Nenhum tempo adicional é necessário para pesquisar na árvore SBB.
32. • Inserção
• A chave a ser inserida é sempre inserida após o apontador vertical mais
baixo na árvore.
• Dependendo da situação anterior à inserção podem aparecer dois
apontadores horizontais.
• Neste caso: é necessário realizar uma transformação.
• O procedimento insere da arvore SBB é igual ao procedimento da arvore
sem balanceamento, porem ele chama outro procedimento interno que
possui dois parâmetros a mais:
33. • Transformações para manter as propriedades da árvore SBB caso ocorra dois
ponteiros horizontais consecutivos: EE, DD, ED, DE
36. Inserção de uma sequência de chaves em uma árvore SBB inicialmente vazia:
Inserir as chaves 7, 5, 10
Inserir as chaves 2, 4
Inserir as chaves 9, 3, 6
37. • Procedimento Retira
• O procedimento retira também contém um outro procedimento interno
IRetira que possui interface com um parâmetro a mais.
• O procedimento IRetira utiliza outros três procedimentos:
• EsqCurto e DirCurto: chamados quando um nodo folha é retirado da
arvore a esquerda ou direita respectivamente;
• Antecessor: chamado quando o nodo retirado possui dois descendentes;
39. Análise
• O custo para manter a propriedade SBB é exatamente o custo para percorrer o
caminho de pesquisa para encontrar a chave, seja para inseri-la ou para retirá-la:
• Logo, este custo é O(log N).
• O número de comparações em uma pesquisa com sucesso:
• melhor caso : C(n) = O(1) (igual ao da árvore binaria)
• pior caso : C(n) = O(log n) (melhor que a árvore binária)
• caso médio : C(n) = O(log n) (igual ao da árvore binaria)
• Na prática o caso médio para Cn é cerca de 2% pior que o Cn de uma arvore
completamente balanceada (Ziviane e Tompa 1982).
41. Próxima Aula
• Seção 5.4 – Pesquisa Digital
• Seção 5.5 – Transformação de Chave Hashing
• Seção 6.3 – Pesquisa em Memória Secundária (Árvore de Pesquisa)
• Bibliografia Básica
Ziviani, Nivio. Projeto de Algoritmos com Implementações em Pascal e C. 3ª
Edição, 2010. Editora Cengage Learning.