Computação III...–TAMASSIA, R. e GOODRICH, M. T. Estruturas de Dados e Algoritmos em JAVA; Porto...

42
Computação III Professor: Mtr. David Batard Lorenzo Instituto Superior para as Tecnologias de Informção e Telecomunicação ISUTIC

Transcript of Computação III...–TAMASSIA, R. e GOODRICH, M. T. Estruturas de Dados e Algoritmos em JAVA; Porto...

Computação III Professor: Mtr. David Batard Lorenzo

Instituto Superior para as Tecnologias de Informção e Telecomunicação

ISUTIC

Aula prática

TDA Árvore.

Bibliografia da matéria

–Aho, Hopcroft, Ullman. Estructura de Datos y

Algoritmos.

– CORMEN, T. H. et al. Algoritmos: Teoria e Prática; Rio

de Janeiro: Editora Campus, 2002.

– Thomas H. Cormen, Charles E. Leiserson. Introduction

to Algorithms. Second Edition.

–TAMASSIA, R. e GOODRICH, M. T. Estruturas de

Dados e Algoritmos em JAVA; Porto Alegre: Editora

Bookman, 2002.

Objectivo

• Caracterizar o TDA Árvore e sua implementação

Lembrete

Tipo de Dado Abstrato

• Modelo matemático

• consiste em um conjunto de dados

• e as operações definidas para esseconjunto de dados.

Lembrete

Tipo de Dado Abstrato

TDA

Estrutura de Dados

Operações

A estrutura de árvore expressa umarelação hierárquica entre os elementosde um conjunto dado.

Exemplos de conceitos recursivos

- Os ficheiros e pastas de um disco de computadores alojam-seem pastas…

Grafo

A

B C

ED HGF

I LKJ O M N P

Definição de Árvore segundo a teoria de grafo

Uma árvore é um grafo conexo, nãodirigido e acíclico.

Definição recursiva de árvore

(Horowitz, Capítulo 5)

r

T1T2 Tn-1 Tn

Terminologia

Inicialmente introduziremos os conceitos de:

• Pai (Padre)

• Filho (Hijo)• Irmão (Hermano)

• Grau (Grado)

• Folha (Hoja)

Outras terminologias

Baseados no conceito de caminho se define: •O nível ou profundidade de um nó•O peso ou altura de um nó•O peso ou altura de uma árvore• Ancestro. Ancestro próprio•Descendente. Descendente próprio

Percorridos

Os percorridos de uma árvore emprofundidade podem serrealizados de três formas:• percorrido em preorden• percorrido em entreorden• percorrido em postorden

A lista de um dos percorridos empreorden dos nós da árvore é:

D,E,F,G,H,I,J,K,L,M

JH

I

G

D

M

K L

F

A lista de um dos percorridos ementreorden dos nós da árvore é:

F,E,D,I,H,G,K,J,L,M

JH

I

G

D

M

K L

F

A lista de um dos percorridos em postorden dos nós da árvore é:

F,E,I,H,K,L,J,M,G,D

JH

I

G

D

M

K L

F

Algoritmo para percorrido em Preorden

Lista PercorridoEmPreorden ()

Criar lista

Preorden(lista)

retornar lista

fim // PercorridoEmPreorden

Algoritmo para percorrido em Preorden

Preorden (Lista L )

L.Adicionar(raiz)

Desde i = 0 Até grau-1 Com Passo 1 Fazer

Subárvore[i].Preorden (L)

fim // Preorden

/* note que para grau = 0 nunca se executa o ciclo*/

Percorrido na largura

No percorrido na largura visita-se o nó do nível 0 (isto é a raiz), aseguir todos os nós do nível 1,depois todos os nós do nível 2 eassim sucessivamente.

O percorrido

na largura

da árvore

Tc é:

D, E, G, F, H, J, M, I, K, L

JH

I

G

D

M

K L

F

Algoritmo para Percorrido na largura

Lista Na_Largura( )

Criar L

Criar FilaAux

FilaAux.Adicionar(arvore)

Enquanto ! FilaAux.Vazia()

arvoreActual = FilaAux.Extrair()

L.Adicionar(arvoreActual.Raiz())

Desde i=0 Até arvoreActual.Grau()-1 Com Passo 1 Fazer

FilaAux.Adicionar(arvoreActual.Subarvore[i])

FIm // Enquanto

retornar L

FIM // Na_Largura

•Realizar o percorridos nasdiferentes ordens dadas dasárvores descritas na classe.

Tarefa

O TDA árvore

Operações

•Raíz() Retorna o objeto contidona raiz da árvore.

•ÉFolha() Retorna True se aárvore é uma folha

• Grau() Retorna o Grau da árvore

•Altura() Retorna o peso ou altura daárvore

•Subarvore(i) Retorna uma cópia dei-esimo subárvore da árvore

•AdicionarSubarvore(Arvore)Adiciona uma árvore à lista desubárvores.

•PercorridoEmPreorden()•PercorridoEmEntreorden()•PercorridoEmPostorden()

Implementam os percorridos empreorden, entreorden e postordenda árvore.

•PercorridoNaLargura ()Implementa o percorrido na largurada árvore.

Estruturas de dados para a representação de árvores

ArvoreGeral

-raiz : T-subArvores : Lista <ArvoreGeral<T>>

+ ArvoreGeral(raiz: T) + Raiz() : T+ EFolha () : boolean+ Grau() : int+ Altura(): int+ SubArvore(pos: int) : ArvoreGeral<T>+ AdicionarSubArvore(n: ArvoreGeral<T>) + PreOrden() : Lista<T>+ PostOrden(): Lista<T>+ EntreOrden(): Lista<T>+ NaLargura(): Lista<T>

T

Exercicio

•Implementar o TDA Árvore usando a representação de lista de filhos..

public class ArvoreGeral<T> {

private T raiz;

private ListaSE<ArvoreGeral<T>> SubArvores;

• public ArvoreGeral(T pRaiz) {

this.raiz = pRaiz;

SubArvores = new ListaSE<ArvoreGeral<T>>();

}

//Retorna o objeto contido na raiz da árvore

• public T getRaiz() {

return raiz; }

//Retorna true se a árvore é uma folha

• public boolean EFolha() {

return SubArvores.Vazia(); }

/*Retorna o Grau da árvore */• public int Grau(){

return SubArvores.Extensão(); }

//Retorna uma cópia de i-esimo subárvoreda árvore• public ArvoreGeral<T> SubArvore(int pos)

throws Exception {

if(pos<0 ||pos>=SubArvores.Extensão()) throw new Exception("Posicão inválida");

return SubArvores.Obter(pos); }

//Adiciona uma árvore à lista de subárvores• public void

AdicionarSubArvore(ArvoreGeral<T> n) {SubArvores.Adicionar(n); }

//Elimina uma árvore da lista de subárvores, a árvore da posicão dada

• public void EliminardSubArvore(int pos) throws Exception {

if(pos<0||pos>=SubArvores.Extensão())

throw new Exception("Posicão inválida");

SubArvores.Extrair(pos); }

//Retorna o peso ou altura da árvore

• public int Altura() {

if (EFolha()) return 0;

int max = 0;

int h;

for (int i = 0; i < SubArvores.Extensão(); i++){

try {

h = SubArvores.Obter(i).Altura();

if (h > max) max = h;

} catch (Exception e){ e.printStackTrace(); }

}//ciclo for ends

return max+1;

}

// Método principal para o percorrido em PreOrdem

• public ListaSE<T> PercorridoEmPreOrdem() {

ListaSE<T> Resultado=new ListaSE<T>();

PreOrdem(Resultado);

return Resultado;

}

// Método axiliar recursivo para fazer o percorrido PreOrdem

• private void PreOrdem(ListaSE<T> Resultado){

if (Grau() == 0) Resultado.Adicionar(raiz);

else {

Resultado.Adicionar(raiz);

for (int i = 0; i < SubArvores.Extensão(); i++) {

SubArvores.Obter(i).PreOrden(Resultado);

}

}

}

//Método principal para o percorrido em EntreOrdem

• public ListaSE<T> PercorridoEmEntreOrdem(){

ListaSE<T> Resultado=new ListaSE<T>();

EntreOrdem(Resultado);

return Resultado;

}

//// Método axiliar recursivo para fazer o percorrido EntreOrdem

private void EntreOrdem(ListaSE<T> Resultado){

if(Grau() == 0) Resultado.Adicionar(raiz);

else {

SubArvores.Obter(0).EntreOrdem(Resultado);

Resultado.Adicionar(raiz);

for (int i = 1; i < SubArvores.Extensão(); i++) {

SubArvores.Obter(i).EntreOrden(Resultado);}

} //else

} // EntreOrdem

// Método principal para o percorrido em PostOrdem

• public ListaSE<T> PercorridoEmPostOrdem(){

ListaSE<T> Resultado=new ListaSE<T>();

PostOrdem(Resultado);

return Resultado;

}

// Método axiliar recursivo para fazer o percorrido PostOrdem

• private void PostOrdem(ListaSE<T> Resultado){

if(Grau() == 0) Resultado.Adicionar(raiz);

else {

for (int i = 0; i < SubArvores.Extensão(); i++) {

SubArvores.Obter(i).PostOrden(Resultado);

} //for

Resultado.Adicionar(raiz);

} //else

}

public ListaSE<T> PercorridoNaLargura() {

ListaSE<T> Resultado=new ListaSE<T>();

Fila<ArvoreGeral<T>> F = new Fila<ArvoreGeral<T>>();

F.Adicionar(this);

while (!F.Vazia()) {

ArvoreGeral<T> A = F.Extrair();

Resultado.Adicionar(A.getRaiz());

for (int i = 0; i < A.Grau(); i++) {

F.Adicionar(A.SubArvore(i));

}

}// while

return Resultado;

}

}// Class acabou