Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o...

82
Árvores Estruturas de Dados Prof. Vilson Heck Junior

Transcript of Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o...

Page 1: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores

Estruturas de DadosProf. Vilson Heck Junior

Page 2: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

INTRODUÇÃOÁrvores

Page 3: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Introdução

• Árvores são estruturas de dadosutilizadas para armazenar e recuperardados de forma rápida e eficiente;

• Árvores não são lineares, ou seja, oselementos não são dispostos em formasequencial;

Page 4: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Introdução

• Árvores são amplamente utilizadas epossuem diversas estratégias deimplementação;

• Cada estratégia tem um conjuntoespecífico de algoritmos paraarmazenamento e recuperação dosdados;

– Árvores genealógicas são análogas àsestruturas de dados árvores.

Page 5: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

COMPOSIÇÃOÁrvores

Page 6: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Composição

• As árvores são compostas por:

– Nodos/Nós: são os elementos inseridos emuma árvore;

– Arestas: fazem a ligação entre 2 nodos;

Page 7: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Composição

• O primeiro Nodo de uma árvore échamado de Raiz;

– Todos os demais nodos da árvore serão seusdescendentes;

• Nodos que não tenham filhos serãochamados de folhas, ou terminais;

• Os demais nodos são ditosintermediários, ou às vezes: galhos.

Page 8: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Composição

• As principais propriedades de cada nodosão:

– Ordem/Grau: Indica o número de filhos queo nodo possui;

– Nível/Altura/Profundidade: Indica adistância do nodo em relação à raiz;

• A árvore também possuí valores de ordem e denível.

– Ambos os valores serão assumidos com base nomaior valor encontrado em qualquer nodo.

Page 9: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB

D FE

G IH J

Nível 0Nó A = Raiz – Ordem 2

Nível 1Nó B = Galho – Ordem 3Nó C = Folha – Ordem 0

Nível 2Nó D = Folha – Ordem 0Nó E = Galho – Ordem 4Nó F = Folha – Ordem 0

Nível 3Nó G = Folha – Ordem 0Nó H = Folha – Ordem 0Nó I = Folha – Ordem 0Nó J = Folha – Ordem 0

Árvore: Nível 3 e Ordem 4

Nós / Nodos

Arestas

Níve

l

Ordem

Page 10: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

OUTRAS PROPRIEDADESÁrvores

Page 11: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Propriedades

• Qualquer nodo de uma árvore pode serchamado de raiz para uma sub-árvore;

• Um Nodo Pai é um nodo conectadodiretamente acima de outro nodo;

• Um Nodo Filho é um nodo conectadodiretamente abaixo de outro nodo;

• Nodos Irmãos compartilham o mesmonodo pai;

Page 12: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Propriedades

• Nodos Ancestrais são todos os nodosque estão acima de um nodo, comligação direta ou indireta;

• Nodos Descendentes são todos os nodosque estão abaixo de um nodo, comligação direta ou indireta;

Page 13: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

EXERCÍCIOSÁrvores

Page 14: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB D

F

E

G IH MK N

O P TSR U X

765

#

4

&

3WY Z

8 9

Page 15: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

ÁRVORES BINÁRIASÁrvores

Page 16: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores Binárias

• Árvores Binárias são árvores com todas aspropriedades vistas anteriormente, porémcom algumas regras:

– A Ordem máxima da árvore é 2;

– Todos os nodos de uma sub-árvore, do filho àdireita, serão maiores do que o nodo pai;

– Todos os nodos de uma sub-árvore, do filho àesquerda, serão menores do que o nodo pai;

• Geralmente chamadas de “Árvores bináriasde pesquisa”;

Page 17: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores Binárias

– O número máximo de nodos para cada nívelde uma árvore binária é determinada pelaequação:

níveltotal 2

Page 18: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB

D FE G

IH

J

Nível 0Nó A = Raiz – Ordem 2

Nível 1Nó B = Galho – Ordem 2Nó C = Galho – Ordem 2

Nível 2Nó D = Folha – Ordem 0Nó E = Galho – Ordem 2Nó F = Folha – Ordem 0Nó G = Folha – Ordem 0

Nível 3Nó H = Galho – Ordem 1Nó I = Folha – Ordem 0

Árvore Binária: Nível 4 e Ordem 2

Nós / Nodos

Arestas

Níve

l

Ordem

Nível 4Nó J = Folha – Ordem 0

Page 19: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

EXEMPLO:

ÁRVORE BINÁRIA EM MDA

Árvores

Page 20: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

IMPLEMENTADO ÁRVORES BINÁRIAS

Árvores

Page 21: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Árvores são implementadas comelementos dinâmicos, assim como naslistas encadeadas;

• Nas listas, tínhamos apenas um próximoelemento. Nas árvores, cada elementoterá “dois próximos”:

– Filho da Esquerda; e

– Filho da Direita.

Page 22: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

public class Nodo

{

public int numero;

//outros atributos

//...

public Nodo esquerda;

public Nodo direita;

public Nodo pai; //Opcional

}

Page 23: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Para implementar operações em árvores,é necessário percorrer diversos nodosdela;

– Para inserir um novo elemento, é necessáriodescer a árvore nível por nível até encontrara posição adequada ao novo elemento;

– Para remover um elemento, é necessáriodescer a árvore até encontrar o elemento aser removido;

Page 24: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Vale lembrar das regras maisimportantes de navegação nas árvoresbinárias de pesquisa:

– Elementos menores estarão à esquerda;

– Elementos maiores estarão à direita.

Page 25: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Inserção:– Se a raiz estiver vazia:

• Insere na raiz.

– Senão:• Navega pela árvore (subindo de nível)

comparando o valor a ser inserido com osvalores dos nodos visitados;– Se Menor – Esquerda; e

– Se Maior – Direita;

• Quando encontrar um nodo sem filho para olado por onde deveria seguir, insere o novoelemento nesta posição.

Page 26: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

public static 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;

}}

Page 27: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Pesquisa:– Se a raiz estiver vazia:

• Não encontrado!– Senão:

• Navega pela árvore (subindo de nível)comparando o valor pesquisado com os valoresdos nodos visitados:– Igual – Encontrado!– Menor – Desloca à Esquerda;– Maior – Desloca à Direita;

– Se percorrer toda a árvore sem encontrar:• Não encontrado!

Page 28: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementandopublic Nodo pesquisar(int nro) {

Nodo aux = raiz;while (aux != null) {

if (aux.numero == nro) {return aux;

} else if (nro < aux.numero) {aux = aux.esquerda;

} else {aux = aux.direita;

}}return null;

}

Page 29: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Navegar por todos os Nodos:

6

82

1 4

3

Page 30: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Listar Conteúdo da Árvore:

– A listagem da árvore pode ser feitas de três formas básicas:

• Em ordem:– 1, 2, 3, 4, 6, 8

• Pré-ordem:– 6, 2, 1, 4, 3, 8

• Pós-ordem:– 1, 3, 4, 2, 8, 6

6

82

1 4

3

Page 31: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Listar Conteúdo da Árvore:

– Pode ser implementado com diversas estratégias:

• Recursividade;

• Pilha;

• Busca do subsequente.6

82

1 4

3

Page 32: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Listar com Recursividade

public static void listar(Nodo inicio) {

if (inicio == null) {

return;

}

listar(inicio.esquerda);

System.out.println(inicio.numero);

listar(inicio.direita);

}

Page 33: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos:– Aux = Pesquisar(Nodo)– Se Aux == NULL

• não encontrado!– Senão:

• Se Aux for raiz:– Sem filhos– Com um filho– Com dois filhos

• Senão– Sem filhos– Com um filho– Com dois filhos

Page 34: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos:– Aux = Pesquisar(Nodo)– Se Aux == NULL

• não encontrado!– Senão:

• Se Aux for raiz:– Sem filhos– Com um filho– Com dois filhos

• Senão– Sem filhos– Com um filho– Com dois filhos

Page 35: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos – Raiz sem filhos:

– Raiz = null;

Page 36: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos:– Aux = Pesquisar(Nodo)– Se Aux == NULL

• não encontrado!– Senão:

• Se Aux for raiz:– Sem filhos– Com um filho– Com dois filhos

• Senão– Sem filhos– Com um filho– Com dois filhos

Page 37: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos – Raiz com um filho:

– Raiz = Filho Único da Raiz;

Page 38: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos:– Aux = Pesquisar(Nodo)– Se Aux == NULL

• não encontrado!– Senão:

• Se Aux for raiz:– Sem filhos– Com um filho– Com dois filhos

• Senão– Sem filhos– Com um filho– Com dois filhos

Page 39: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos – Raiz com dois filhos:

– Substituto = Subsequente(Raiz); //Aux

– Substitui (Raiz pelo Substituto);

Page 40: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos:– Aux = Pesquisar(Nodo)– Se Aux == NULL

• não encontrado!– Senão:

• Se Aux for raiz:– Sem filhos– Com um filho– Com dois filhos

• Senão– Sem filhos– Com um filho– Com dois filhos

Page 41: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos – Não Raiz sem filhos:

– PaiAux = Aux.Pai;

– Se (PaiAux.Esquerda == Aux) então

• PaiAux.Esquerda = null;

– Senão

• PaiAux.Direita = null;

Page 42: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos:– Aux = Pesquisar(Nodo)– Se Aux == NULL

• não encontrado!– Senão:

• Se Aux for raiz:– Sem filhos– Com um filho– Com dois filhos

• Senão– Sem filhos– Com um filho– Com dois filhos

Page 43: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos – Não Raiz / 1 filho:

– PaiAux = Aux.Pai;

– FilhoAux = Aux.Filho; (esquerda, ou direita)

– Se (PaiAux.Esquerda == Aux) então

• PaiAux.Esquerda = FilhoAux;

– Senão

• PaiAux.Direita = FilhoAux;

Page 44: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos:– Aux = Pesquisar(Nodo)– Se Aux == NULL

• não encontrado!– Senão:

• Se Aux for raiz:– Sem filhos– Com um filho– Com dois filhos

• Senão– Sem filhos– Com um filho– Com dois filhos

Page 45: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando

• Remoção de Nodos – Não Raiz / 2 filhos:

– Substituto = Subsequente(Aux);

– Substitui (Aux pelo Substituto);

Page 46: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementandoprivate static boolean substituirNodo(Nodo original, Nodo novo) {

if (original == null || novo == null) {

return false;

}

Nodo pai = original.pai;

if (pai != null) {

if (pai.esquerda == original) {

pai.esquerda = novo;

} else {

pai.direita = novo;

}

}

novo.pai = pai;

Nodo filho = original.esquerda;

if (filho != null) {

filho.pai = novo;

}

novo.esquerda = filho;

filho = original.direita;

if (filho != null) {

filho.pai = novo;

}

novo.direita = filho;

return true;

}

Continuação...

Page 47: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando (1/3)public static boolean remover(Nodo rem) {

if (rem == null) {

return false;

}

//Informação paterna

Nodo pai = rem.pai;

//Existe um substituto único ou nenhum?

Nodo subst;

if (rem.esquerda == null || rem.direita == null) {

//Ambos são null? sem substituto

if (rem.esquerda == rem.direita) {

subst = null;

} else { //Se direita vazia, substituto esta na esquerda e vice versa

if (rem.direita == null) {

subst = rem.esquerda;

} else {

subst = rem.direita;

}

}

Page 48: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando (2/3)//Se tiver um pai, atualiza vinculo dos filhos, senão atualiza a raiz.

if (pai != null) {

if (pai.esquerda == rem) {

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;

}

Page 49: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Implementando (3/3)//Se chegarmos aqui é por que o nodo excluído tem dois filhos. (Subsequente)

//Procuramos o elemento imediatamente maior e que não tenha filho a esquerda

Nodo proximo = rem.direita;

while (proximo.esquerda != null) {

proximo = proximo.esquerda;

}

//Removemos o nodo que tem apenas um filho

remover(proximo); //Recursividade

//Inserimos o nodo "próximo removido" no lugar do "removido"

substituirNodo(rem, proximo);

//Se estivermos excluindo a raiz, atualiza ela

if (pai == null) {

raiz = proximo;

}

return true;

}

Page 50: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Trabalho

• Implemente um Árvore Binária de Pesquisa para realizar a inserção, pesquisa, remoção e listagem de um cadastro de alunos. Os alunos serão cadastrados por:

– Nome (chave, String)

– Matricula (long)

– Nome do curso (String)

Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com base nos nomes dos alunos. Exemplo de função para comparar strings de forma “alfabética”:

Page 51: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

ÁRVORES BALANCEADASÁrvores

Imagem: Natalie Jeremijenko

Page 52: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores

• O pior cenário para uma árvore bináriade pesquisa é quando uma sequência denúmeros é inserida já em ordem:

– Crescente; ou

– Decrescente.

Page 53: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvore não Balanceada

• Entrada: 2, 5, 8, 10, 15

2

5

8

10

15

Page 54: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores

• Para melhorar o tempo de busca emárvores binárias de pesquisa, é possívelaplicar técnicas de balanceamento,conforme ilustração a seguir:

Page 55: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Balanceando a Árvore

2

5

8

10

15

Page 56: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Balanceando a Árvore

2

5

8

10

15

Page 57: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Balanceando a Árvore

2

5

8

10

15

Page 58: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores AVL

• O conceito de Árvore AVL foi criado em1962 por Adelson-Velsky e Landis;

• É uma árvore binária de pesquisabalanceada;

• O primeiro diferencial:– cada nodo possuí um campo numérico

indicando a diferença de altura para cadasubárvore filha:• 0 : subárvores com mesma altura;

• 1 : subárvore direita é 1 nível maior;

• -1 : subárvore esquerda é 1 nível maior;

Page 59: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB

D E

IH

Nível 0Nó A = Raiz – Ordem 2

Nível 1Nó B = Galho – Ordem 2Nó C = Galho – Ordem 2

Nível 2Nó D = Galho – Ordem 2Nó E = Galho – Ordem 1

Nível 3Nó H = Folha – Ordem 0Nó I = Folha – Ordem 0

Árvore Binária NÃO AVL: Nível 3 e Ordem 2

Nós / Nodos

Arestas

Níve

lOrdem

Nível 4

Page 60: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB

D E

IH

Nível 0Nó A: Dif = -2

Nível 1Nó B: Dif = -1Nó C: Dif = 0

Nível 2Nó D: Dif = 0Nó E: Dif = 0

Nível 3Nó H: Dif = 0Nó I: Dif = 0

Diferenças

Page 61: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores AVL

• Principal Regra:

– Nenhum nodo pode permanecer comdiferença maior de nível em qualquersubárvore maior do que 1:

• 2

• – 2

– Sempre que esta condição não for satisfeita,devem ocorrer rotações na árvore, até queela esteja balanceada, ou seja, comqualquer subárvore

Page 62: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB

D E

IH

Nível 0Nó A: Dif = -2

Nível 1Nó B: Dif = -1Nó C: Dif = 0

Nível 2Nó D: Dif = 0Nó E: Dif = 0

Nível 3Nó H: Dif = 0Nó I: Dif = 0

Alguma |diferença| > 1 ?

Page 63: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores AVL

• Rotações:

Diferença Diferença do filho Tipo de Rotação

2

1 Simples: à esquerda

0 Simples: à esquerda

-1 Dupla: filho para a direita e pai para a esquerda

-2

1 Dupla: filho para a esquerda e pai para a direita

0 Simples: à direita

-1 Simples: à direita

Page 64: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB

D E

IH

Nível 0Nó A: Dif = -2

Nível 1Nó B: Dif = -1Nó C: Dif = 0

Nível 2Nó D: Dif = 0Nó E: Dif = 0

Nível 3Nó H: Dif = 0Nó I: Dif = 0

Diferença do Filho Maior

Page 65: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Árvores AVL

• Rotações:

Diferença Diferença do filho Tipo de Rotação

2

1 Simples: à esquerda

0 Simples: à esquerda

-1 Dupla: filho para a direita e pai para a esquerda

-2

1 Dupla: filho para a esquerda e pai para a direita

0 Simples: à direita

-1 Simples: à direita

Page 66: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB

D E

IH

Rotação à Direita

Page 67: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

CB

D E

IH

Rotação à Direita

Page 68: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

C

B

D

EIH

Rotação à Direita

Page 69: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

C

B

D

EIH

Rotação à Direita

Page 70: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

C

B

D

EIH

Rotação à Direita

Page 71: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

C

B

D

EIH

Rotação à Direita

Page 72: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

A

C

B

D

EIH

Árvore Binária AVL: Nível 2 e Ordem 2

Nível 0Nó B: Dif = 0

Nível 1Nó D: Dif = 0Nó A: Dif = 0

Nível 2Nó H: Dif = 0Nó I: Dif = 0Nó E: Dif = 0Nó C: Dif = 0

Nível 3

Níve

lOrdem

Page 73: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

ROTAÇÕESÁrvores AVL

Page 74: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Rotação Simples à Esquerdaprivate boolean RotacaoEsquerda(Nodo centro){

if (centro == null)return false;

Nodo aux = centro.Direita;if (aux == null)

return false;

//Atualizar a raiz?if (centro == raiz)

raiz = aux;

//Troca os paisaux.Pai = centro.Pai;centro.Pai = aux;

if (aux.Pai != null){

Nodo pai = aux.Pai;if (pai.Esquerda == centro)

pai.Esquerda = aux;else

pai.Direita = aux;}//Troca os filhosNodo troca = aux.Esquerda;aux.Esquerda = centro;centro.Direita = troca;return true;

}

Page 75: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Rotação Simples à Direitaprivate boolean RotacaoDireita(Nodo centro){

if (centro == null)return false;

Nodo aux = centro.Esquerda;if (aux == null)

return false;

//Atualizar a raiz?if (centro == raiz)

raiz = aux;

//Troca os paisaux.Pai = centro.Pai;centro.Pai = aux;

if (aux.Pai != null){

Nodo pai = aux.Pai;if (pai.Esquerda == centro)

pai.Esquerda = aux;else

pai.Direita = aux;}//Troca os filhosNodo troca = aux.Direita;aux.Direita = centro;centro.Esquerda = troca;return true;

}

Page 76: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Rotação Dupla à Esquerda

private boolean RotacaoDuplaEsquerda(Nodo centro)

{

if (centro == null)

return false;

Nodo aux = centro.Direita;

if (aux == null)

return false;

boolean retorno = RotacaoDireita(aux);

if (retorno == false)

return false;

return RotacaoEsquerda(centro);

}

Page 77: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Rotação Dupla à Direitaprivate boolean RotacaoDuplaDireita(Nodo centro)

{

if (centro == null)

return false;

Nodo aux = centro.Esquerda;

if (aux == null)

return false;

boolean retorno = RotacaoEsquerda(aux);

if (retorno == false)

return false;

return RotacaoDireita(centro);

}

Page 78: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

OUTRAS ALTERAÇÕESÁrvores AVL

Page 79: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Alterações Classe Nodo

• Novos atributos:

public int AltEsq;

public int AltDir;

public int Dif;

• Construtor:

this.Dif = 0;

this.AltDir = 0;

this.AltEsq = 0;

Page 80: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

AlturaSubArvore – Calculo Difpublic int AlturaSubArvore(Nodo atual){

if (raiz == null)return 0;

if (atual == null)atual = raiz;

if (atual.Esquerda == null)atual.AltEsq = 0;

elseatual.AltEsq = AlturaSubArvore(atual.Esquerda) + 1;

if (atual.Direita == null)atual.AltDir = 0;

elseatual.AltDir = AlturaSubArvore(atual.Direita) + 1;

atual.Dif = atual.AltDir - atual.AltEsq;if (atual.AltDir > atual.AltEsq)

return atual.AltDir;else

return atual.AltEsq;}

Page 81: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Balanceamento da Árvore (1/2)public void BalancearArvore(Nodo atual) {

if (raiz == null)return;

if (atual == null)atual = raiz;

if (atual.Dif > 1){

if (atual.Direita.Dif == -1)RotacaoDuplaEsquerda(atual);

elseRotacaoEsquerda(atual);

return;}

Page 82: Árvores - docente.ifsc.edu.brdocente.ifsc.edu.br/vilson.junior/ed/08_Arvores.pdf · Como nome é o campo chave, a separação esquerda/direita dos elementos deverá ser feita com

Balanceamento da Árvore (2/2)

if (atual.Dif < -1){

if (atual.Esquerda.Dif == 1)RotacaoDuplaDireita(atual);

elseRotacaoDireita(atual);

return;}if (atual.Esquerda != null)

BalancearArvore(atual.Esquerda);if (atual.Direita != null)

BalancearArvore(atual.Direita);}