Você está na página 1de 48

rvores

Prof. Cristhian Heck, M.Sc.


1

rvores

INTRODUO

Introduo
rvores so estruturas de dados utilizadas para armazenar e recuperar dados de forma rpida e eficiente; rvores no so lineares, ou seja, os elementos no so dispostos em forma sequencial;

Introduo
rvores so amplamente utilizadas e possuem diversas estratgias de implementao;
Cada estratgia tem um conjunto especfico de algoritmos para armazenamento e recuperao dos dados;

rvores genealgicas so anlogas s estruturas de dados rvores.


4

rvores

COMPOSIO

Composio
As rvores so compostas por: Nodos/Ns: so os elementos inseridos em uma rvore; Arestas: fazem a ligao entre 2 nodos;

Composio
O primeiro Nodo de uma rvore chamado de Raiz; Todos os demais nodos da rvore sero seus descendentes; Nodos que no tenham filhos sero chamados de folhas, ou terminais; Os demais nodos so ditos intermedirios, ou s vezes: galhos.
7

Composio
As principais propriedades de cada nodo so: Ordem/Grau: Indica o nmero de filhos que o nodo possui; Nvel/Altura/Profundidade: Indica a distncia do nodo em relao raiz;
A rvore tambm possu valores de ordem e de nvel. Ambos os valores sero assumidos com base no maior valor encontrado em qualquer nodo.
8

rvore: Nvel 3 e Ordem 4


Ns / Nodos Nvel 0 N A = Raiz Ordem 2

A
Arestas

Nvel 1 N B = Galho Ordem 3 N C = Folha Ordem 0 Nvel 2 N D = Folha Ordem 0 N E = Galho Ordem 4 N F = Folha Ordem 0 Nvel 3 N G = Folha Ordem 0 N H = Folha Ordem 0 N I = Folha Ordem 0 N J = Folha Ordem 0

Nvel

Ordem
G H I J

rvores

OUTRAS PROPRIEDADES

10

Propriedades
Qualquer nodo de uma rvore pode ser chamado de raiz para uma sub-rvore;
Um Nodo Pai um nodo conectado diretamente acima de outro nodo; Um Nodo Filho um nodo conectado diretamente abaixo de outro nodo; Nodos Irmos compartilham o mesmo nodo pai;
11

Propriedades
Nodos Ancestrais so todos os nodos que esto acima de um nodo, com ligao direta ou indireta;
Nodos Descendentes so todos os nodos que esto abaixo de um nodo, com ligao direta ou indireta;

12

rvores

EXERCCIOS

13

7 14

&

rvores

RVORES BINRIAS

15

rvores Binrias
rvores Binrias so rvores com todas as propriedades vistas anteriormente, porm com algumas regras: A Ordem mxima da rvore 2; Todos os nodos de uma sub-rvore, do filho direita, sero maiores do que o nodo pai; Todos os nodos de uma sub-rvore, do filho esquerda, sero menores do que o nodo pai;
Geralmente chamadas de rvores binrias de pesquisa;

16

rvores Binrias
O nmero mximo de nodos para cada nvel de uma rvore binria determinada pela equao:

total 2

nvel

17

rvore Binria: Nvel 4 e Ordem 2


Ns / Nodos Nvel 0 N A = Raiz Ordem 2

A
Arestas

Nvel 1 N B = Galho Ordem 2 N C = Galho Ordem 2

Ordem
H I

Nvel 2 N D = Folha Ordem 0 N E = Galho Ordem 2 N F = Folha Ordem 0 N G = Folha Ordem 0


Nvel 3 N H = Galho Ordem 1 N I = Folha Ordem 0

Nvel

Nvel 4 N J = Folha Ordem 0

18

rvores

IMPLEMENTADO RVORES BINRIAS

19

Implementando
rvores so implementadas com elementos dinmicos, assim como nas listas encadeadas;
Nas listas, tnhamos apenas um prximo elemento. Nas rvores, cada elemento ter dois prximos: Filho da Esquerda; e Filho da Direita.

20

Implementando
public class Nodo { public int numero; //outros atributos //... public Nodo Esquerda; public Nodo Direita; public Nodo Pai; //Opcional }

21

Implementando
Construtor para classe nodo:

public Nodo(int nro) { this.numero = nro; this.Esquerda = null; this.Direita = null; this.Pai = null; }

22

Implementando
Para implementar operaes em rvores, necessrio percorrer diversos nodos dela;
Para inserir um novo elemento, necessrio descer a rvore nvel por nvel at encontrar a posio adequada ao novo elemento;

Para remover um elemento, necessrio descer a rvore at encontrar o elemento a ser removido;
23

Implementando
Vale lembrar das regras mais importantes de navegao nas rvores binrias de pesquisa:
Elementos menores estaro esquerda; Elementos maiores estaro direita.

24

Implementando
Insero: Se a raiz estiver vazia: Insere na raiz. Seno: Navega pela rvore (subindo de nvel) comparando o valor a ser inserido com os valores dos nodos visitados; Se Menor Esquerda; e Se Maior Direita; Quando encontrar um nodo sem filho para o lado por onde deveria seguir, insere o novo elemento nesta posio.

25

public void Inserir(Nodo novo) { novo.Direita = null; novo.Esquerda = null; novo.Pai = null; if (raiz == null) raiz = novo; else { Nodo aux = raiz; while (aux != null) { if (novo.numero < aux.numero) { if (aux.Esquerda == null) { aux.Esquerda = novo; break; } aux = aux.Esquerda; }

else { if (aux.Direita == null) { aux.Direita = novo; break; } aux = aux.Direita; } } novo.Pai = aux; } }

26

Implementando
Pesquisa:

Se a raiz estiver vazia: No encontrado! Seno: Navega pela rvore (subindo de nvel) comparando o valor pesquisado com os valores dos nodos visitados: Igual Encontrado! Menor Desloca Esquerda; Maior Desloca Direita; Se percorrer toda a rvore sem encontrar: No encontrado!

27

Implementando
public Nodo Pesquisar(int nro) { Nodo aux = raiz; while (aux != null) { if (aux.numero == nro) return aux; if (nro < aux.numero) aux = aux.Esquerda; else aux = aux.Direita; } return null;
28

Implementando
Navegar por todos os Nodos:

4 29

Implementando
Listar Contedo da rvore: A listagem da rvore pode ser feitas de trs formas bsicas: Em ordem: (crescente ou decrescente) 1, 2, 3, 4, 6, 8 6 Pr-ordem:
Pais processados antes

6, 2, 1, 4, 3, 8 Ps-ordem:
Filhos processados antes

4
30 3

1, 3, 4, 2, 8, 6

Implementando
Listar Contedo da rvore: Pode ser implementado com diversas estratgias: Recursividade; Pilha; Busca do subsequente.
6

4 31 3

Listar com Recursividade


public static void Listar(Nodo inicio) { if (inicio == null) { return; } Listar(inicio.Esquerda); System.out.println(inicio.numero); Listar(inicio.Direita); }

32

Implementando
Remoo de Nodos:

Aux = Pesquisar(Nodo) Se Aux == NULL


no encontrado!

Seno:
Se Aux for raiz:

Sem filhos Com um filho Com dois filhos


Seno

Sem filhos Com um filho Com dois filhos

34

Implementando
Remoo de Nodos Raiz sem filhos:

Raiz = null;

35

Implementando
Remoo de Nodos:

Aux = Pesquisar(Nodo) Se Aux == NULL


no encontrado!

Seno:
Se Aux for raiz:

Sem filhos Com um filho Com dois filhos


Seno

Sem filhos Com um filho Com dois filhos

36

Implementando
Remoo de Nodos Raiz com um filho:

Raiz = Filho nico da Raiz;

37

Implementando
Remoo de Nodos:

Aux = Pesquisar(Nodo) Se Aux == NULL


no encontrado!

Seno:
Se Aux for raiz:

Sem filhos Com um filho Com dois filhos


Seno

Sem filhos Com um filho Com dois filhos

38

Implementando
Remoo de Nodos Raiz com dois filhos:

Substituto = Subsequente(Raiz); //Aux Substitui (Raiz pelo Substituto);

39

Implementando
Remoo de Nodos:

Aux = Pesquisar(Nodo) Se Aux == NULL


no encontrado!

Seno:
Se Aux for raiz:

Sem filhos Com um filho Com dois filhos


Seno

Sem filhos Com um filho Com dois filhos

40

Implementando
Remoo de Nodos No Raiz sem filhos:
PaiAux = Aux.Pai; Se (PaiAux.Esquerda == Aux) ento PaiAux.Esquerda = null; Seno PaiAux.Direita = null;

41

Implementando
Remoo de Nodos:

Aux = Pesquisar(Nodo) Se Aux == NULL


no encontrado!

Seno:
Se Aux for raiz:

Sem filhos Com um filho Com dois filhos


Seno

Sem filhos Com um filho Com dois filhos

42

Implementando
Remoo de Nodos No Raiz / 1 filho:
PaiAux = Aux.Pai; FilhoAux = Aux.Filho; (esquerda, ou direita) Se (PaiAux.Esquerda == Aux) ento PaiAux.Esquerda = FilhoAux; Seno PaiAux.Direita = FilhoAux;
43

Implementando
Remoo de Nodos:

Aux = Pesquisar(Nodo) Se Aux == NULL


no encontrado!

Seno:
Se Aux for raiz:

Sem filhos Com um filho Com dois filhos


Seno

Sem filhos Com um filho Com dois filhos

44

Implementando
Remoo de Nodos No Raiz / 2 filhos:

Substituto = Subsequente(Aux); Substitui (Aux pelo Substituto);

45

Implementando (1/3)
public boolean Remover(Nodo remover) { if (remover == null) return false; //Informao paterna Nodo pai = remover.Pai; //Existe um substituto nico ou nenhum? Nodo subst; if (remover.Esquerda == null || remover.Direita == null) { //Ambos so null? sem substituto if (remover.Esquerda == remover.Direita) subst = null; else { //Se direita vazia, substituto esta na esquerda e vice versa if (remover.Direita == null) subst = remover.Esquerda;

46

Implementando (2/3)
else subst = remover.Direita; } //Se tiver um pai, atualiza vinculo dos filhos, seno atualiza a raiz. if (pai != null) { if (pai.Esquerda == remover) pai.Esquerda = subst; else pai.Direita = subst; } else raiz = subst; //Se tiver um filho substituto, atualiza seu vinculo paterno if (subst != null) subst.Pai = pai; return true; }

47

Implementando (3/3)
//Se chegarmos aqui por que o nodo excludo tem dois filhos. (Subsequente) //Procuramos o elemento imediatamente maior e que no tenha filho a esquerda

Nodo proximo = remover.Direita; while (proximo.Esquerda != null) proximo = proximo.Esquerda; //Removemos o nodo que tem apenas um filho Remover(proximo); //Recursividade //Inserimos o nodo "prximo removido" no lugar do "removido" SubstituirNodo(remover, proximo); //Se estivermos excluindo a raiz, atualiza ela if (pai == null) raiz = proximo; return true; } 48

Implementando
private boolean SubstituirNodo(Nodo original, Nodo novo) { if (original == null || novo == null) return false; Nodo pai = original.Pai; if (pai != null) { if (pai.Esquerda == original) Continuao... pai.Esquerda = novo; else filho = original.Direita; pai.Direita = novo; if (filho != null) } filho.Pai = novo; novo.Pai = pai; novo.Direita = filho; Nodo filho = original.Esquerda; if (filho != null) return true; filho.Pai = novo; } novo.Esquerda = filho;

49

Você também pode gostar