Árvores 2 caminhamentos e construção. caminhamentos em árvore binária um caminhamento, ou...

87
ÁRVORES 2 ÁRVORES 2 Caminhamentos e Construção

Upload: internet

Post on 17-Apr-2015

107 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

ÁRVORES 2ÁRVORES 2

Caminhamentos e Construção

Page 2: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Caminhamentos em árvore binária

• Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente todos os nós da árvore, sendo cada nó visitado exatamente uma vez.

• Um caminhamento completo sobre uma árvore produz um seqüência linear de nós, de maneira que cada nó tem um nó seguinte e um nó anterior.

Page 3: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Caminhamentos em árvore binária

• No caso da árvore binária existem três tipos de caminhamento em profundidade mais frequentemente utilizados:– LRN (pós-ordem)– NLR (pré-ordem)– LNR (in-ordem)

Page 4: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Caminhamento LRN

• O caminhamento LRN, o início é feito pela raiz, depois visitamos o ramo esquerdo de cada nó, em seguida o ramo direito e, finalmente, o próprio nó.

• Esse caminhamento é recursivo já que cada um dos ramos esquerdo e direito pode ser considerado uma subárvore

Page 5: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

-

* /

A C +

D E

B

O caminhamento LRN para a árvore abaixo fica assim:

Page 6: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

*

A B

Subárvore esquerda

A

B

*

Subárvore esquerda

Subárvore direita

Nó da subárvore

Page 7: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

/

C +

D E

Subárvore direita

C Subárvore esquerda

Page 8: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

+

D E

Subárvore direita

D

E

+

Subárvore esquerda

Subárvore direita

Nó da subárvore

- Nó da árvore

Page 9: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Caminhamento LRN

• Para a árvore, se considerarmos que os nós folhas são os operandos e os ramos são os operadores, este caminhamento fornece a notação posfixa.

• A B * C D E + / -

Page 10: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Caminhamento NLR

• O caminhamento NLR também inicia pela raiz, primeiro é visitado o próprio nó, em seguida a subárvore esquerda e por último a subárvore direita.

Page 11: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

-

* /

A C +

D E

B

O caminhamento NLR para a árvore abaixo fica assim:

Page 12: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

*

A B

- Nó da árvore

Subárvore esquerda

*

A

B

Nó da subárvore

Subárvore esquerda

Subárvore direita

Page 13: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

/

C +

D E

Subárvore direita

/

C

Nó da subárvore

Subárvore esquerda

Page 14: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

+

D E

Subárvore direita

+

D

E

Nó da subárvore

Subárvore esquerda

Subárvore direita

Page 15: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Caminhamento NLR

• Como no caminhamento NLR, os operadores precedem os operandos, ele é conhecido como pre-ordem.

• - * A B / C + D E

Page 16: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Caminhamento LNR

• No caminhamento LNR, começando pela raiz, primeiro é visitada a subárvore esquerda, em seguida o nó e finalmente a subárvore direita.

Page 17: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

-

* /

A C +

D E

B

O caminhamento LNR para a árvore abaixo fica assim:

Page 18: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

*

A B

Subárvore esquerda

A

B

*

Subárvore esquerda

Nó da subárvore

Subárvore direita

Page 19: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

/

C +

D E

- Nó da árvore

Subárvore direita

Page 20: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

/

C

+

D E

Subárvore esquerda

Nó da subárvore

Subárvore direita

Page 21: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

• O caminhamento LNR é conhecido também como in-ordem pois fornece a notação infixa quando a árvore armazena expressões aritméticas

• A * B - C / D + E

+

D

E

Subárvore esquerda

Nó da subárvore

Subárvore direita

Page 22: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

59

22 69

13 61 78

71 83

49

35

26 41 75

Verificar os caminhamentos LRN, NLR e LNR

Page 23: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

• Na árvore anterior, para o caminhamento LNR, a seqüência fornecida está em ordem crescente. Uma árvore binária na qual o caminhamento LNR fornece uma lista ordenada é chamada de árvore binária de classificação.

• Uma árvore binária de classificação é uma árvore binária onde todos os nós da subárvore esquerda são menores ou iguais ao valor da raiz.

• Esta propriedade se aplica recursivamente a cada nó da árvore.

Page 24: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

• Os caminhamentos que vimos até aqui foram caminhamentos em profundidade. Há uma outra forma de caminhamento, não tão usada que é o caminhamento em largura.

• No caminhamento em largura, visitamos os nós da árvore por níveis da árvore visitando todos os nós de um nível da árvore da esquerda para a direita e então partindo para o próximo nível.

• No exemplo dado anteriomente o percurso em largura ficaria: - * / A B C + D E

Page 25: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Implementação de Árvore Binária

• Tal como dito para as outras árvores, árvores binárias podem ser implementadas usando-se vetor ou alocação dinâmica.

• A implementação com vetores só é conveniente se a árvore for completa.

• Para guardar os nós é feito o percurso em largura com a raiz sendo o primeiro nó do array.

Page 26: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Implementação de Árvore Binária

• Considerando que em Java o primeiro índice do vetor é 0 e não 1, teremos:

• Em Java o pai de um nó i sempre estará na posição (i-1) div 2.

• Para um nó na posição i seus filhos (se existirem) estarão na posição 2i+1 e 2i+2

Page 27: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Implementação de Árvore Binária• Se a árvore não for completa podemos transformá-la em

uma árvore cheia pelo acréscimo de nós fantasmas. Isto deve ser indicado em algum campo do nó. Assim, cada elemento do array consistirá de dois campos: um para conter o valor do nó e o outro para indicar se o nó é nulo ou não. Na figura abaixo, usamos um campo booleano para indicar se o nó é valido (T) ou se é um nó nulo (F).

Page 28: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Implementação de Árvore Binária

• As mesmas expressões apresentadas para uma árvore completa se aplicam também aqui. A diferença é que agora temos de testar, através do campo Ind, se o nó é nulo ou não.

• Em muitas situações, a representação de árvores através de arrays pode não ser tão eficiente. O motivo disso é que gastamos muita memória para armazenar os nós nulos, além de termos que rearrumar o array toda vez que houver uma remoção. Entretanto, se não for permitido remoções na árvore e se o número máximo de nós for conhecido, o uso de arrays pode ser uma solução bastante útil.

Page 29: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Implementação de Árvore BináriaRepresentação Dinâmica

• A representação dinâmica de uma árvore binária é feita com a utilização de variáveis dinâmicas onde cada nó contém, além da informação, dois ponteiros: um para apontar para a subárvore esquerda e o outro para apontar para a subárvore direita como mostrado na figura abaixo.

Page 30: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Implementação de Árvore BináriaRepresentação Dinâmica

• Para facilitar a implementação de alguns algoritmos iremos manter no nó mais um ponteiro que aponta para o seu pai. Além disso, o formato do nó em Java que iremos utilizar nos nossos algoritmos será o seguinte:

Page 31: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

boolean temFilhoEsq() { if (filhoEsq == null) return false; else return true; } boolean temFilhoDir() { if (filhoDir == null) return false; else return true; }} //Fim da classe Node

class Node{ String nome; Node filhoEsq; Node filhoDir; Node pai; //Construtor principal, recebe o conteúdo e o pai do nó Node(String n, Node noPai) { nome = n; pai = noPai; filhoDir = filhoEsq = null; } //Construtor para a raiz, na verdade chama o de dois Node(String n) { this(n,null); }

Page 32: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Implementação de Árvore Binária

• A vantagem de se utilizar estruturas dinâmicas para a representação de árvores binárias é a possibilidade delas crescerem ou diminuírem durante a execução do programa.

Page 33: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Inserção de Nós em Uma Árvore Binária

• Para poder inserir um nó em uma árvore binária precisamos antes conhecer quem será seu pai e se esse nó será o filho esquerdo ou o filho direito, como mostrado na seguinte listagem:

Page 34: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

public boolean insere(Node noPai, String info, char tipoFilho) { Node aux; boolean Ok = false; if (noPai == null) //Significa que estou inserindo a raiz { aux = new Node(info); raiz = aux; Ok = true; } else { if ((tipoFilho == 'E') && (noPai.temFilhoEsq())) { System.out.println("*** ERRO: Impossível inserir, já possui filho esquerdo!"); Ok = false; return false; } else if ((tipoFilho == 'D') && (noPai.temFilhoDir())) { System.out.println("*** ERRO: Impossível inserir, já possui filho direito! ***"); Ok = false; return false; } aux = new Node(info,noPai); if (tipoFilho == 'E') noPai.insFilhoEsq(aux); else noPai.insFilhoDir(aux); Ok = true; } return Ok; }//Fim do método insere

Page 35: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Navegando Através de Uma Árvore Binária

• Agora que já sabemos como construir uma árvore binária, vamos discutir como navegamos através dela para visitar todos os seus nós. Já vimos que o termo visitar consiste em processar o item de um nó para fazer qualquer tipo de operação, seja simplesmente imprimir seu conteúdo ou fazer uma operação mais complexa. A navegação será feita através de um dos percursos vistos anteriormente, ou seja em pré-ordem, em ordem simétrica, em pós-ordem e em níveis. Esses tipos de percursos podem ser implementados usando recursividade ou sem o uso dela.

• Vejamos a seguir o código para os três tipos de percurso:

Page 36: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Percurso in-ordem

public void inOrdemRec(Node atual) { if (atual != null) { inOrdemRec(atual.getFilhoEsq()); System.out.println(atual.getNome()); inOrdemRec(atual.getFilhoDir()); } }

Page 37: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Percurso Pré-ordem

public void preOrdemRec(Node atual) { if (atual != null) { System.out.println(atual.getNome()); inOrdemRec(atual.getFilhoEsq()); inOrdemRec(atual.getFilhoDir()); } }

Page 38: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Percurso Pós-ordem

public void posOrdemRec(Node atual) { if (atual != null) { inOrdemRec(atual.getFilhoEsq()); inOrdemRec(atual.getFilhoDir()); System.out.println(atual.getNome()); } }

Page 39: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Procurando um Dado na Árvore

• Para encontrar um dado na árvore devemos percorrê-la usando um dos percursos vistos acima. Se encontrarmos o dado que estamos procurando iremos retornar o endereço do nó correspondente. Para inserirmos um dado na árvore antes de inserir o dado temos que ter o endereço do pai do dado, ou seja, temos que pesquisar o endereço do pai do dado caso este nó exista na árvore. O código seguinte é recursivo baseado em um percurso pré-ordem.

Page 40: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

public boolean pesquisa(Node inicio, String procurado) { if (inicio != null) { if (procurado.equals(inicio.getNome())) { achou = inicio; return true; } pesquisa(inicio.getFilhoEsq(), procurado); pesquisa(inicio.getFilhoDir(), procurado); } return false; }

Page 41: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Remoção de Nós em Uma Árvore Binária

• A remoção de nós em uma árvore binária requer uma série de testes para determinar como os filhos dos nós serão reatados. As seguintes situações podem ocorrer:

• 1) O nó a ser removido não tem filhos, isto é, ele é uma folha, como é o caso do nó 35 da seguinte árvore. Neste caso basta atualizar o ponteiro do pai para que ele aponte para uma subárvore vazia:

Page 42: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Remoção de Nós em Uma Árvore Binária

2) O nó a ser removido tem somente um filho (esquerdo ou direito), como é o caso do nó 40 da seguinte figura. Neste caso fazemos com que o pai aponte para o filho do nó removido.

3) O nó a ser removido possui dois filhos. Nesse caso simplesmente não removemos o nó e acusamos um erro. Mais adiante veremos uma variação de uma árvore binária, a árvore binária de busca, onde existe uma informação extra que nos possibilita remover esse tipo de nó.

Page 43: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

public boolean remove(Node no) { boolean resp = false; if (no != null) { if (no.filhoEsq != null) { If (no.filhoDir != null) { System.out.println("O nó não pode ser removido porque tem 2 filhos"); return false; } else //Situação em que só tem filho esquerdo { if (no == raiz) //Caso o nó seja raiz não pode testar o pai dela { raiz = no.filhoEsq; raiz.removePai(); return true; } else { char posicao = getPosNo(no); //Qual a posicao do no em relacao ao pai if (posicao == 'E') no.pai.filhoEsq = no.filhoEsq; else no.pai.filhoDir = no.filhoEsq; no.filhoEsq.pai = no.pai; return true; } } }//Fim de só ter filho esquerdo

Page 44: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

else //Situação em que só tem filho direito ou mesmo filho nenhum {if (no == raiz) //Caso o nó seja raiz não pode testar o pai dela{raiz = no.filhoDir;if (!estaVazia()) raiz.removePai();return true;}else{ char posicao = getPosNo(no); if (posicao == 'E') no.pai.filhoEsq = no.filhoDir; else no.pai.filhoDir = no.filhoDir; if (no.filhoDir != null) no.filhoDir.pai = no.pai; return true;} } } return false; }

Page 45: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Exercícios propostos

1) Qual a altura mínima de uma árvore binária que possui 15 nós?2) a) Desenhar uma árvore binária que contenha 10 nós e tenha altura 5.    b) Desenhar uma árvore binária que contenha 14 nós e tenha altura 5.3) Uma árvore binária contém os seguintes valores: 1, 3, 7, 2, 12    a) Desenhar duas árvores de altura máxima contendo os dados.    b) Desenhar duas árvores completas onde o valor do pai é maior do que qualquer um dos seus filhos.4) Desenhar todas as possíveis árvores contendo 3 nós.

Page 46: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Exercícios Propostos

5) Dada a seguinte árvore, pede-se para percorrê-la usando os percursos pré-ordem, em ordem simétrica e pós-ordem.

Page 47: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Exercícios Propostos

6) Uma árvore binária tem 10 nós. Ao se percorrer a árvore em pré-ordem e em ordem simétrica, o resultado é o seguinte:

Pré-ordem: J C B A D E F I G HOrdem simétrica:   A B C E D F J G I HPede-se para desenhar a árvore.

7) Uma árvore binária tem 8 nós. Ao se percorrer a árvore em pós-ordem e em ordem simétrica, o resultado é o seguinte:

Pós-ordem: F E C H G D B AOrdem simétrica:   F C E A B H D GPede-se para desenhar a árvore.

8) Desenhar a árvore binária que representa a seguinte expressão aritmética:

(C + D + A * B) * (E + F)

Page 48: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Árvores Binárias de BuscaNos capítulos anteriores usamos listas lineares para armazenar informações. Nessas listas vimos que algumas operações eram bastante rápidas, com ordem O(1), enquanto que outras eram muito lentas, com ordem O(N). Em aplicações que envolvem grande quantidade de dados, o uso desses tipos de listas é proibitivo. O que precisamos é de uma estrutura que aproveita o que tem de melhor nas listas encadeadas e o que tem de melhor nas listas seqüenciais ordenadas. Essa estrutura é obtida com as árvores binárias de busca.

Uma árvore binária de busca é uma árvore binária onde, para qualquer nó, as seguintes propriedades são válidas:

• Todos os itens da subárvore esquerda são menores do que a raiz;

• Todos os itens da subárvore direita são maiores do que a raiz;

• Cada subárvore é por si mesma uma árvore binária de busca.

Page 49: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Exemplo de Árvore Binária de Busca

• A árvore é chamada de árvore de busca porque nós podemos seguir um caminho específico quando tentamos encontrar um elemento. Começando pela raiz, nós seguimos pela subárvore esquerda se o valor da chave for menor do que o valor do nó corrente. Caso contrário seguimos pela subárvore direita. Por exemplo, para encontrar o valor 40 na árvore anterior precisamos efetuar 4 comparações.

Page 50: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Operações em Uma Árvore Binária de Busca

A seguir mostramos a implementação das principais operações que podem ser feitas em uma árvore binária de busca.

Percursos na ÁrvoreOs algoritmos de percursos em uma árvore binária de busca são idênticos àqueles vistos no capítulo anterior. Por exemplo, tomando como referência a árvore da figura 9.1, obtemos as seguintes seqüências:

Pré-ordem: 50, 45, 35, 15, 5, 40, 38, 36, 42, 43, 46, 65, 75, 70, 85

Pós-ordem: 5, 15, 36, 38, 43, 42, 40, 35, 46, 45, 70, 85, 75, 65, 50

Simétrica: 5, 15, 35, 36, 38, 40, 42, 43, 45, 46, 50, 65, 70, 75, 85

Como podemos ver acima, o percurso na ordem simétrica nos dá uma seqüência muito útil para ser utilizada na vida prática, pois produz uma lista ordenada.

Page 51: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Operações em Uma Árvore Binária de Busca

• Método busque:• Usado para verificar se já existe a informação a ser inserida.

Caso não encontre a informação serão retornadas informações que permitirão que a nova informação seja inserida no local correto.

• O retorno deste método é um objeto da classe volta criado para este fim. Um objeto da classe Volta possui um boolean que informa se o nó foi encontrado ou não, um Node que retorna o endereço do nó em que a informação foi encontrada, caso ela foi encontrada e um char que indica – caso a informação não foi encontrada – se ela seria filho da esquerda ou da direita.

• Caso encontre a informação procurada é retornado o nó que a contém em getNo e true em achou. Caso não encontre a informação é retornado false em achou, getNo vai conter o pai do nó e getTF retorna um char informando se o filho vai ser da esquerda 'E' ou da direita 'D'.

Page 52: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Operações em Uma Árvore Binária de Busca

• Inserção de um nó na árvore:• Embora uma árvore binária de busca a rigor possa

ter nós com chaves repetidas, vamos admitir em nosso estudo que a chave seja única. Assim, para incluir um nó primeiro pesquisamos a existência do nó na árvore. Se existir, então acusaremos um erro, caso contrário incluímos o nó usando como pai o ponteiro retornado na rotina de busca.

Page 53: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Operações em Uma Árvore Binária de Busca

• Remover um nó da árvore:• Se o nó a ser removido for uma folha ou se tiver

somente um filho podemos usar o mesmo algoritmo apresentado para remover um nó nas árvores binárias, uma vez que, após a remoção, a árvore continua satisfazendo as condições de uma árvore binária de busca.

• Para o caso do nó ter dois filhos, como é o caso do nó 30 da árvore da figura seguinte, após a remoção desse nó, criamos duas subárvores órfãs que devem ser reatadas à árvore.

Page 54: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Operações em Uma Árvore Binária de Busca

• Nós iremos utilizar o seguinte algoritmo para reatar essas subárvores de modo que as propriedades da árvore binária de busca sejam mantidas:

Page 55: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Operações em Uma Árvore Binária de Busca

• Pesquisamos na subárvore esquerda do nó a ser removido o nó que possui o maior valor, no exemplo acima esse nó é o 28;

• Copiamos o maior valor no nó a ser removido

Page 56: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Operações em Uma Árvore Binária de Busca

• Finalmente removemos da árvore o nó que contém o maior valor. Como o maior valor de uma subarvore de busca sempre será sua ponta mais avançada a direita ele sempre será uma folha ou terá apenas um filho esquerdo, cairemos, portanto, nos casos anteriores.

Page 57: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Complexidade de uma Árvore Binária de Busca

• Quase todas as operações envolvendo árvores consiste em descer a árvore, nível a nível, até encontrar um nó particular. Quanto tempo leva para fazer isso? Se a árvore for cheia, como na figura abaixo cerca da metade de todos os nós da árvore se encontram no último nível (para ser mais exato existe na realidade um nó a mais no último nível do que no restante da árvore). Assim, cerca da metade de todas as buscas, inserções e remoções requerem a busca de um nó que se encontra no último nível.

Page 58: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Complexidade de uma Árvore Binária de Busca

• Durante o processo de busca nós precisamos visitar um nó em cada nível. Assim nós podemos ter uma idéia de quanto tempo leva esse processo, sabendo o número de níveis que a árvore possui.

• A relação entre o número de nós (N) e o número de níveis (L) em uma árvore cheia é dado por:

N = 2L - 1• ou seja

L = Log2(N+1)• Concluímos então que a complexidade das três operações

(busca, inclusão e remoção) para uma árvore binária de busca cheia é O(Log2N).

Page 59: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Complexidade de uma Árvore Binária de Busca

• Se a árvore não for cheia, a análise se torna difícil uma vez que em geral não se tem nenhuma idéia do formato que a árvore terá. A única certeza que teremos é que a complexidade será maior do que o da árvore cheia. Porém, quanto maior será?

• Antes de tudo é fácil descobrir o pior caso que acontece quando a árvore é construída a partir de chaves que chegam já ordenadas. Nesse caso a árvore se torna completamente degenerada, isto é, ela se transforma em uma lista linear, como mostrado na figura abaixo.

Page 60: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Complexidade de uma Árvore Binária de Busca

• No pior caso teremos de fazer em média N/2 comparações, ou seja sua complexidade é O(N).

• No entanto não podemos sempre ser otimista nem pessimista. Isto é, devemos fazer a análise considerando que as chaves chegam em ordem aleatória. Neste caso chega-se a seguinte fórmula que nos dá aproximadamente o número médio de comparações para encontrar uma chave específica:

• Número médio de comparações? 1,386 * Log2N• Podemos concluir então que, em média, o número de

comparações a serem feitas para encontrar um dado na árvore binária de busca é aproximadamente 38,6% maior do que para o melhor caso.

Page 61: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Árvores de busca AVL

• As árvores binárias foram projetadas para conseguirmos um acesso rápido aos dados entretanto dependendo da ordem de chegada dos dados a árvore pode ficar degenerada como podemos ver a seguir. Considere duas árvores Binárias de Busca obtidas de uma árvore vazia e da inserção dos números de 1 a 5. Na primeira árvore os números foram inseridos na ordem 2,1,4,3,5, na segunda foram inseridos na ordem 1, 2, 3, 4, 5.

Page 62: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Árvores de busca AVL

• Vemos que a segunda ABB é melhor que a primeira pois esta possui apenas 3 níveis ao passo que a primeira possui 5 níveis. Podemos dizer que a segunda é mais balanceada que a primeira. Esta situação fica ainda mais clara se inserirmos os números de 1 a 7 em ordem crescente e na ordem 4, 2, 6, 1, 3, 5, 7.

• Um problema das Árvores Binárias de Busca é que mesmo O(log n) sendo o tempo médio de processamento das operações de busca, inserção e remoção no pior caso ele sempre permanece O(n). Isso acontece em geral porque não sabemos nada sobre a forma da árvore. Se tivéssemos uma árvore balanceada poderíamos garantir ter O(log n).

Page 63: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Árvores de busca AVL

• Por esta razão, em 1962, dois matemáticos russos G. M. Adelson-Velskii e E. M. Landis criaram uma estrutura de árvore binária balanceada os quais denominaram de árvores AVL.

• Uma árvore AVL é uma árvore binária de busca onde a diferença entre as duas subárvores de cada nó é de no máximo uma unidade.

• As árvores AVL têm uma representação similar às árvores binárias de busca, sendo que as operações de inserção e remoção têm de monitorar constantemente as alturas das subárvores esquerda e direita do nó. Para manter essa informação iremos adicionar mais um campo no nó da árvore, chamado balanço, como mostrado abaixo.

Page 64: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Árvores de busca AVLclass Node{ String nome; Node filhoEsq; Node filhoDir; int Balanco; Node pai; . . .}

• O valor do balanço será a diferença entre as alturas das subárvores esquerda e direita:

• Balanço = Altura(Subárvore_esquerda) - Altura(Subárvore_direita)

• Se o valor do balanço for negativo indica que o nó está "mais pesado" no lado direito, enquanto que se seu valor for positivo, o nó está "mais pesado" no lado esquerdo. Se for zero o nó está equilibrado.

Page 65: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Árvores de busca AVL

• Em uma árvore AVL o balanço deve estar sempre no intervalo de -1 a 1. Como exemplo, a seguinte figura mostra duas árvores AVL com o valor dos balanços:

Page 66: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Inserção em Árvores de Busca AVL

• A inserção de um nó em uma árvore AVL é semelhante à inserção em uma árvore binária de busca. No entanto, a depender do local onde o nó será inserido, a árvore resultante pode deixar de ser balanceada. Por exemplo, a figura seguinte mostra a árvore resultante ao ser inserida a chave 5. Mesmo após a inserção, a árvore permaneceu balanceada.

Page 67: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Inserção em Árvores de Busca AVL

• Observe agora o que acontece ao ser inserida a chave 60 na mesma árvore:

• Neste caso a árvore resultante ficou desbalanceada.

Page 68: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Inserção em Árvores de Busca AVL

• A pista para saber se uma árvore vai continuar balanceada ou não após uma inserção é a seguinte:

• • Se no caminho onde o nó vai ser inserido todos os balanços têm o valor zero, a árvore resultante vai continuar balanceada;

• • Se o caminho onde o nó vai ser inserido existir algum balanço diferente de zero a árvore resultante continuará balanceada se a inserção for feita no lado "mais leve". Se a inserção for feita no lado "mais pesado" a árvore ficará desbalanceada.

Page 69: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Inserção em Árvores de Busca AVL• Como o ponto crítico em uma árvore AVL é a presença de

balanços diferente de zero, iremos dar atenção especial ao nó com balanço diferente de zero mais próximo do lugar onde o novo nó será inserido. Esse nó iremos denominar de pivô. Por exemplo, considere a árvore:

• Se formos inserir 15, o pivô será o nó 20, ao passo que se formos inserir 48, o pivô será o nó 45. Logo Pivô será o nó com balanço diferente de zero mais próximo do local onde o novo nó será inserido.

Page 70: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Inserção em Árvores de Busca AVL• Após cada inserção em uma árvore AVL temos

que verificar se algum nó ficou desbalanceado, isto é se a diferença de altura entre suas duas subarvores ficou maior que 1.

• Como iremos saber se a inserção de um nó vai desbalancear a árvore?– Se no caminho onde o nó vai ser inserido todos os

nós tem balanço igual a zero, ela vai continuar balanceada.

– Se no caminho onde o nó vai ser inserido tiver algum balanço diferente de zero, ela vai continuar balanceada se a inserção for feita no lado mais “leve”. Caso o nó seja inserido no lado mais “pesado” vai desbalancear.

Page 71: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL

• Se a árvore ficar desbalanceada precisamos efetuar algumas transformações na árvore para que ela volte a ficar balanceada. Essas transformações são denominadas rotações, podendo ocorrer um dos seguintes casos:– Rotação simples para a direita– Rotação simples para a esquerda– Rotação dupla, uma para a esquerda outra para

a direita– Rotação dupla, uma para a direita e outra para a

esquerda

Page 72: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL

• Rotação simples para a direita

• - Ocorre quando o pivô e seu filho esquerdo se tornam mais pesados do lado esquerdo

• ( O pivô torna-se filho direito de seu filho esquerdo, este toma o antigo lugar do pivô e quem era filho direito do filho esquerdo passa a ser filho esquerdo do que era o pivô).

Page 73: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL

• Exemplo de rotação simples para a direita:

Page 74: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL• Rotação simples para a esquerda• - Ocorre quando o pivô e seu filho direito ficam mais

pesados do lado direito.

• (O pivô torna-se filho esquerdo o que era seu filho direito e o que era filho esquerdo do filho direito passa a ser filho direito do pivô.)

Page 75: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL

• Exemplo de rotação simples para a direita:

Page 76: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL• Rotação dupla, uma para a esquerda outra para a direita

• - Ocorre quando o pivô se torna mais pesado do lado esquerdo e seu filho esquerdo se torna mais pesado do lado direito.

Page 77: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL• (é feita uma rotação simples para a esquerda em torno do

filho do pivô seguida de uma rotação simples para a direita em torno do pivô).

• Exemplo de rotação dupla uma para a esquerda e outra para a direita:

Page 78: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL• Rotação dupla, uma para a direita e outra para a esquerda

• - Ocorre quando o pivô se torna mais pesado do lado direito e seu filho direito se torna mais pesado do lado esquerdo

Page 79: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Balanceando a árvore AVL• (é feita uma rotação para a direita em torno do filho direito do

pivô seguida de uma rotação para a esquerda em torno do pivô.)

• Exemplo de uma rotação dupla, uma para direita e outra para esquerda

Page 80: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Remoção em Árvore AVL

• A remoção de um nó em uma árvore AVL pode também provocar seu desbalanceamento. Para rebalancear a árvore usamos um processo semelhante ao que foi usado na inserção, através do uso de rotações.

Page 81: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Complexidade de Árvores AVL

• A eficiência das árvores AVL depende da aplicação, uma vez que nós temos um esforço adicional para manter a árvore balanceada quando inserimos e removemos nós. Se essas operações forem executadas repetidamente, o tempo gasto será significante.

• Não existe o pior caso numa árvore AVL uma vez que sua estrutura se aproxima de uma árvore binária completa. Assim, a operação de busca será sempre de ordem O(Log2N). Evidências empíricas indicam que aproximadamente 50% das inserções e remoções requerem rotações. Concluímos então que as árvores AVL deverão ser usadas somente em situações onde a operação de busca é a operação dominante.

Page 82: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

ExercíciosDadas as seguintes arvores AVL insira os elementos pedidos rebalanceando a arvore conforme necessário.1)Insira o elemento 5 na arvore abaixo 30 / \ / \ 10 40 / \ / \ 8 202) Insira o elemento 1 na arvore abaixo 10 / \ / \ 5 30 / \ / \ / \ / \ 3 8 20 40 / / 2

Page 83: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Exercícios3)Insira o elemento 53 na arvore abaixo 40 / \ / \ 32 46 / \ / \ 44 504) Insira o elemento 43 na arvore abaixo 40 / \ / \ 32 46 / \ / \ 44 50

Page 84: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

• 5) Insira o elemento 4 na arvore abaixo• 10• / \• / \• 7 30• / \ / \• / \ / \• 5 8 20 40• /• /• 2• 6) Insira o numero 27 na arvore abaixo• 40• / \• / \• 20 60• / \ / \• / \ / \• 10 30 50 80• / / \• / / \• 5 25 90

Exercícios

Page 85: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

7) Insira o numero 46 arvore abaixo 35 / \ / \ 30 40 / \ / \ / \ / \ 10 33 37 45 / \ \ / \ \ 5 38 47

Exercícios

Page 86: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

Implementações em PascalO seguinte procedimento implementa o algoritmo que efetua uma rotação para direita em torno de um nó.procedure RotacaoParaDireita(No: PNoArvoreBin);{ Procedimento que efetua uma rotação para direita em torno do   nó apontado por No }var  Pai: PNoArvoreBin;begin   if No^.Filho[Esquerdo] = nil then      Exit;   Pai := No;   No  := No^.Filho[Esquerdo];   Pai^.Filho[Esquerdo] := No^.Filho[Direito];   if Pai^.Filho[Esquerdo] <> nil then      Pai^.Filho[Esquerdo]^.PPai := Pai;   No^.PPai := Pai^.PPai;   if No^.PPai^.Filho[Esquerdo] = Pai then      No^.PPai^.Filho[Esquerdo] := No   else      No^.PPai^.Filho[Direito] := No;   No^.Filho[Direito] := Pai;   Pai^.PPai := No;end;

Page 87: ÁRVORES 2 Caminhamentos e Construção. Caminhamentos em árvore binária Um caminhamento, ou percurso, em uma árvore binária é o ato de percorrer sistematicamente

O seguinte procedimento implementa as operações necessárias para efetuar uma rotação para esquerda em torno de um nó.procedure RotacaoParaEsquerda(No: PNoArvoreBin);{ Procedimento que efetua uma rotação para esquerda em torno do   nó apontado por No }var  Pai: PNoArvoreBin;begin   if No^.Filho[Direito] = nil then      Exit;   Pai := No;   No  := No^.Filho[Direito];   Pai^.Filho[Direito] := No^.Filho[Esquerdo];   if Pai^.Filho[Direito] <> nil then      Pai^.Filho[Direito]^.PPai := Pai;   No^.PPai := Pai^.PPai;   if No^.PPai^.Filho[Esquerdo] = Pai then      No^.PPai^.Filho[Esquerdo] := No   else      No^.PPai^.Filho[Direito] := No;   No^.Filho[Esquerdo] := Pai;   Pai^.PPai := No;end;

Implementações em Pascal