109
1 Árvores

Árvores

  • Upload
    laasya

  • View
    28

  • Download
    1

Embed Size (px)

DESCRIPTION

Árvores. Definição. Definição (Árvore)   Uma árvore T é um conjunto finito e não vazio de nós , com as seguintes propriedades: Um certo nó do conjunto, r , é chamado de raiz   da árvore; e - PowerPoint PPT Presentation

Citation preview

Page 1: Árvores

1

Árvores

Page 2: Árvores

2

DefiniçãoDefinição (Árvore)  Uma árvore  T é um conjunto finito e não vazio de nós,

com as seguintes propriedades: 1. Um certo nó do conjunto, r, é chamado de raiz  da

árvore; e

2. Os demais nós são repartidos em sub conjuntos, T1, T2, ..., Tn , cada um dos quais sendo uma árvore.

É usual adotar para a árvore T a notação.

Page 3: Árvores

3

NomenclaturaSeja uma árvore com n 0Grau de um nó é o número de sub-árvores do nóFolha é um nó de grau zero

As raízes ri das sub-árvores Ti são filhas de r

A raiz r da árvore T é pai das raízes ri

Raízes ri e rj de árvores distintas Ti e Tj são irmãs

Page 4: Árvores

4

NomenclaturaNível ou profundidade de um nó ri de uma árvore T é o comprimento do caminho entre a raiz e o nó ri A raiz está no nível zero e seus filhos estão no nível 1 (Preiss) A raiz está no nível 1 e seus filhos estão no nível 2 (Horowitz)

Altura de um nó é o caminho mais longo do nó até uma folhaAltura de uma árvore é a altura do nó raizO pai de um nó é seu ancestral e o pai de seu pai tambémO filho de um nó é seu descendente e o filho de seu filho tambémOrdem de um nó é o grau do nóOrdem de uma árvore é a ordem de seu nó de maior ordem

Page 5: Árvores

5

Nomenclatura

Níveis em versão Horowitz

Page 6: Árvores

6

Representação de árvores por parênteses

A árvore acima teria a seguinte representação usando parênteses:(A(B(E(K, L), F)) , (C (G)), (D(H(M), I, J))))

Page 7: Árvores

7

Outras representações de árvores

Page 8: Árvores

8

Definição (Caminho e Comprimento de Caminho) Para uma árvore T contendo o conjunto de nós R, um caminho em T é definido como uma seqüência não vazia de nós

Caminho e Comprimento de Caminho

do caminho 1kéP

Page 9: Árvores

9

Árvores N-árias

Definição (Árvores N-arias) 

Uma árvore N-aria    T é um conjunto finito de nós  com as propriedades:

1. Ou o conjunto é vazio, T= ; ou

2. O conjunto consiste em uma raiz, R, e exatamente N árvores N-arias distintas. Os demais nós são repartidos em N0 sub conjuntos, T0,T1 , ..., TN-1 , cada qual sendo uma árvore N-aria tal que

Page 10: Árvores

10

Árvore Binária

Definição (Árvore Binária)  Uma árvore binária T é um conjunto finito de nós  com as propriedades:

1. Ou o conjunto é vazio, T = ; ou

2. O conjunto consiste em uma raiz, r, e exatamente duas árvores binárias distintas T L e TR . A árvore TL é chamada árvore da esquerda  de T, e a árvore TR é chamada árvore da direita de  T.

Page 11: Árvores

11

Travessia ou Visitação de Árvores

Existem dois métodos de visitação sistemática a todos os nós de uma árvore: Travessia em largura ou breadth-first traversal

(BFT) Travessia em profundidade ou depth-first

traversal (DFT)

Page 12: Árvores

12

BacktrackingBacktracking é um esquema de solução de uma série de sub problemas cada um dos quais podendo ter múltiplas possíveis soluções e aonde a solução escolhida para um subproblema pode afetar as possíveis soluções dos subproblemas posterioresPara resolver o problema como um todo encontra-se a solução do primeiro sub problema e busca-se recursivamente resolver os outros sub problemas com base na primeira soluçãoSe isto não for possível ou caso se deseje obter todas as possíveis soluções faz-se o backtrack e tenta-se a próxima solução possível para o primeiro sub problema e assim por dianteBacktracking termina quando não mais existem soluções para o primeiro sub problema.

Page 13: Árvores

13

DFT e BFT

depth-first search ou busca em profundidade: Algoritmo de busca em grafos que estende o caminho corrente tanto quanto possível, antes de executar backtracking, até o último ponto aonde houve escolha e tentar outro caminho alternativobreadth first search ou busca em largura: Algoritmo de busca em grafos que tenta todas as possíveis extensões de um passo antes de tentar extensões maiores Isto obriga que se mantenham em memória todos os

caminhos correntes, ou, pelo menos, seus pontos terminais.

Page 14: Árvores

14

BFT (Breadth-First Traversal)

Enquanto a travessia em profundidade (DFT) é definida recursivamente a travessia em largura é melhor compreendida como uma travessia não recursivaA travessia BFT de uma árvore visita os nós em ordem de sua profundidade na árvore BFT primeiro visita todos os nós à profundidade zero

(i. e. a raiz), então todos os nós à profundidade um e assim por diante

Em cada nível os nós são visitados da esquerda para a direita

Page 15: Árvores

15

Árvores Genéricas

Page 16: Árvores

16

Árvores Genéricas

Page 17: Árvores

17

Árvores Binárias

Page 18: Árvores

18

Árvores Binárias

Page 19: Árvores

19

Árvores binárias completas e incompletas

Page 20: Árvores

20

Implementação de árvores binárias por “arrays”

Esta árvore binária tem altura k e número n de nós. n = 2k - 1 = 2 4 - 1 = 15

1 2 3 i 14 15 ou

0 1 2 i 13 14

Page 21: Árvores

21

Implementação de árvores binárias por “arrays”

Se um nó está na posição i, seu pai está na posição i/2 se i 0 (caso o nó inicial seja 0 em vez de 1 o valor será i/2 - 1)O filho esquerdo (mais velho) de i está na posição: 2 i se 2*i n (caso o nó inicial seja 0 em vez de 1 o

valor será 2*i+1) Caso contrário este filho não existe

O filho direito (mais novo) de i está na posição: 2*i + 1 se 2*i + 1n (caso o nó inicial seja 0 em vez de 1

o valor será 2*i+2) Caso contrário este filho não existe

Page 22: Árvores

22

Implementação de árvores binárias por encadeamento

Os nós das árvores binárias podem ser representados da forma

Page 23: Árvores

23

Implementação de árvores binárias por encadeamento

Page 24: Árvores

24

Caminhamento ou percurso sobre árvores binárias

Uma seqüência de nós que contenha todos os nós de uma árvore binária, sem repetições, produz uma relação de ordem total para seus nós que é chamado de caminhamento ou percurso sobre a árvore

Page 25: Árvores

25

Caminhamento ou percurso sobre árvores binárias

São possíveis as seguintes seqüências: ECD - ordem infixa EDC - ordem pós-fixa CED - ordem pré-fixa CDE (pré-fixa) DCE descartadas (infixa) DEC (pós-fixa)

A ordem infixa é a ordem de percurso na qual percorre-se a sub árvore da esquerda, “visita-se” a raiz e percorre-se a sub árvore da direita.A ordem pós-fixa é aquela na qual percorre-se a sub árvore da esquerda, a sub árvore da direita e “visita-se” a raiz.A ordem pré-fixa é aquela na qual “visita-se” a raiz, percorre-se a sub árvore da esquerda e a sub árvore da direita.

Page 26: Árvores

26

Caminhamento ou percurso sobre árvores binárias

Percurso ou notação pré-fixa: ABDHIECFGPercurso ou notação infixa: HDIBEAFCGPercurso ou notação pós-fixa: HIDEBFGCA

Page 27: Árvores

27

Notação Decimal de Dewey

Os nós de uma árvore binária podem ser identificados por uma seqüência de zeros e uns em uma notação análoga à notação decimal de Dewey de acordo com as regras que se seguem. (i) A raiz é representada por “1” (ii) O filho mais velho do nó “x” é representado por “x0” (iii) O filho mais novo do nó “x” é representado por “x1”.

Page 28: Árvores

28

Notação Decimal de Dewey

Notação de Dewey Chave do nó 1 A 10 B 11 C 100 D 101 E 111 F

É comum apresentar todos os nós como seqüências de caracteres com o mesmo

tamanho, igual a altura da árvore, completando-se a árvore binária anterior por:

Notação de Dewey Chave do nó 1bb A 10b B 11b C 100 D 101 E 111 F

onde ‘b’ representa o caractere “branco”.

Page 29: Árvores

29

Implementação Java

Page 30: Árvores

30

Framework de Árvores

Page 31: Árvores

31

Interface Tree

//pgm09_01.txtpublic interface Tree extends Container{ Object getKey (); Tree getSubtree (int i); boolean isEmpty (); boolean isLeaf (); int getDegree (); int getHeight (); void depthFirstTraversal (PrePostVisitor

visitor); void breadthFirstTraversal (Visitor visitor);}

Page 32: Árvores

32

Métodos da Interface TreegetKey

Este método retorna o objeto contido no nó raiz de uma árvore.

getSubtree Este método retorna a -iésima sub árvore de uma árvore.

isEmpty Este método booleano retorna true se a raiz da árvore for uma árvore vazia, i, e. um nó externo.

isLeaf Este método booleano retorna true se a raiz da árvore for um nó folha.

getDegree Este método retorna o grau do nó raiz de uma árvore. Por definição, o grau de um nó externo é zero.

getHeight Este método retorna a altura de uma árvore. Por definição, a altura de uma árvore vazia é -1.

depthFirstTraversal and breadthFirstTraversal Estes métodos são semelhantes ao método accept da classe container. Ambos executam uma

travessia. Todos os nós são visitados sistematicamente. O primeiro aceita um PrePostVisitor e o último aceita um Visitor. Quando um nó for visitado os métodos apropriados do visitor são aplicados ao nó.

Page 33: Árvores

33

Método depthFirstTraversal de AbstractTree// pgm09_02.txtpublic abstract class AbstractTree extends AbstractContainer implements Tree{ public void depthFirstTraversal (PrePostVisitor visitor) {

if (visitor.isDone ()) return;if (!isEmpty ()){ visitor.preVisit (getKey ()); for (int i = 0; i < getDegree (); ++i)

getSubtree (i).depthFirstTraversal (visitor); visitor.postVisit (getKey ());}

} // ...}

Page 34: Árvores

34

Interface PrePostVisitor

//pgm09_03.txt

public interface PrePostVisitor

{

void preVisit (Object object);

void inVisit (Object object);

void postVisit (Object object);

boolean isDone ();

}

Page 35: Árvores

35

Classe Abstrata AbstractPrePostVisitor

//pgm09_04.txtpublic abstract class AbstractPrePostVisitor implements PrePostVisitor{ public void preVisit (Object object)

{} public void inVisit (Object object)

{} public void postVisit (Object object)

{} public boolean isDone ()

{ return false; }}

Page 36: Árvores

36

Classe PreOrder

// //pgm09_05.txtpublic class PreOrder extends AbstractPrePostVisitor{ protected Visitor visitor;

public PreOrder (Visitor visitor){ this.visitor = visitor; }

public void preVisit (Object object){ visitor.visit (object); }

public boolean isDone ()

{ return visitor.isDone (); }}

Page 37: Árvores

37

Classe InOrder

// //pgm09_06.txtpublic class InOrder extends AbstractPrePostVisitor{ protected Visitor visitor;

public InOrder (Visitor visitor){ this.visitor = visitor; }

public void inVisit (Object object){ visitor.visit (object); }

public boolean isDone ()

{ return visitor.isDone (); }}

Page 38: Árvores

38

Classe PostOrder

// //pgm09_07.txtpublic class PostOrder extends AbstractPrePostVisitor{ protected Visitor visitor;

public PostOrder (Visitor visitor){ this.visitor = visitor; }

public void postVisit (Object object){ visitor.visit (object); }

public boolean isDone ()

{ return visitor.isDone (); }}

Page 39: Árvores

39

Exemplo de travessia de Árvores

Visitor v = new PrintingVisitor ();

Tree t = new SomeTree ();

// ...

t.depthFirstTraversal

(new PreOrder (v));

t.depthFirstTraversal

(new InOrder (v));

t.depthFirstTraversal

(new PostOrder (v));

Page 40: Árvores

40

Implementação de BFT (1)

// pgm09_08.txtpublic abstract class AbstractTree extends AbstractContainer implements Tree{ public void breadthFirstTraversal (Visitor

visitor) {

Queue queue = new QueueAsLinkedList ();if (!isEmpty ()) queue.enqueue (this);

} } }

Page 41: Árvores

41

Implementação de BFT (2)

while (!queue.isEmpty () && !visitor.isDone ()){ Tree head = (Tree) queue.dequeue (); visitor.visit (head.getKey ()); for (int i = 0; i < head.getDegree (); ++i) {

Tree child = head.getSubtree (i);if (!child.isEmpty ()) queue.enqueue (child);

} }

} }

Page 42: Árvores

42

Método accept

// pgm09_09.txtpublic abstract class AbstractTree extends AbstractContainer implements Tree{ public void accept (Visitor visitor) { depthFirstTraversal (new PreOrder (visitor)); } // ...}

A escolha de ordem pré-fixa foi arbitrária

Page 43: Árvores

43

Exemplo de varredura de Árvore

Tree tree = new BinaryTree ();

// ...

Enumeration e = tree.getEnumeration ();

while (e.hasMoreElements ())

{

Object obj = e.nextElement ();

System.out.println (obj);

}

Page 44: Árvores

44

Classe interna TreeEnumeration

// pgm09_10.txtpublic abstract class AbstractTree extends AbstractContainer implements Tree{ public Enumeration getEnumeration ()

{ return new TreeEnumeration (); }

protected class TreeEnumerationimplements Enumeration

{protected Stack stack;

// ... } // ...}

Page 45: Árvores

45

Construtor de TreeEnumeration// pgm09_11.txtpublic abstract class AbstractTree extends AbstractContainer implements Tree{ protected class TreeEnumeration

implements Enumeration {

public TreeEnumeration (){ stack = new StackAsLinkedList (); if (!isEmpty ())

stack.push (AbstractTree.this);} }

// ...}

A escolha da enumeração ser por BFT foi arbitrária

Page 46: Árvores

46

Método hasMoreElements da Classe AbstractTree

// pgm09_12.txtpublic abstract class AbstractTree extends AbstractContainer implements Tree{ protected class TreeEnumeration

implements Enumeration {

public boolean hasMoreElements () { return !stack.isEmpty (); }

Page 47: Árvores

47

Método nextElement da Classe AbstractTree

public Object nextElement (){ if (stack.isEmpty ())

throw new NoSuchElementException ();

Tree top = (Tree) stack.pop (); for (int i = top.getDegree () - 1; i >= 0; --i) {

Tree subtree = (Tree) top.getSubtree (i);if (!subtree.isEmpty ()) stack.push (subtree);

} return top.getKey ();}

} }

O empilhamento foi em ordem inversa para a enumeração ser em ordem direta (BFT)

Page 48: Árvores

48

Árvores Genéricas

Page 49: Árvores

49

Classe GeneralTree

// //pgm09_13.txtpublic class GeneralTree extends AbstractTree{ protected Object key; protected int degree; protected LinkedList list;

// ...}

Page 50: Árvores

50

Métodos Construtor e Purge de GeneralTree

// pgm09_14.txtpublic class GeneralTree extends AbstractTree{ protected Object key; protected int degree; protected LinkedList list;

public GeneralTree (Object key) {

this.key = key;degree = 0;list = new LinkedList ();

}

public void purge () {

list.purge ();degree = 0;

} }

Page 51: Árvores

51

Método getSubtree da Classe Generaltree

// pgm09_15.txtpublic class GeneralTree extends AbstractTree{ protected Object key; protected int degree; protected LinkedList list;

public Object getKey (){ return key; }

Page 52: Árvores

52

Método getSubtree da Classe Generaltree

public Tree getSubtree (int i) {

if (i < 0 || i >= degree) throw new IndexOutOfBoundsException ();LinkedList.Element ptr = list.getHead ();for (int j = 0; j < i; ++j) ptr = ptr.getNext ();return (GeneralTree) ptr.getDatum ();

}

} // ...}

Page 53: Árvores

53

Métodos attachSubtree e detachSubtree

public void attachSubtree (GeneralTree t) {

list.append (t);++degree;

}

public GeneralTree detachSubtree (GeneralTree t) {

list.extract (t);--degree;return t;

}

Page 54: Árvores

54

Árvores N-árias

Page 55: Árvores

55

Classe NaryTree

// //pgm09_16.txtpublic class NaryTree extends AbstractTree{ protected Object key; protected int degree; protected NaryTree[] subtree;

// ...}

Page 56: Árvores

56

Construtores de NaryTree (1)

// pgm09_17.txtpublic class NaryTree extends AbstractTree{ protected Object key; protected int degree; protected NaryTree[] subtree;

public NaryTree (int degree) {

key = null;this.degree = degree;subtree = null;

}

Page 57: Árvores

57

Construtores de NaryTree (2)

public NaryTree (int degree, Object key) {this.key = key;this.degree = degree;subtree = new NaryTree[degree];for (int i = 0; i < degree; ++i) subtree [i] = new NaryTree (degree);

} // ...}

Page 58: Árvores

58

Método isEmpty

// pgm09_18.txt

public class NaryTree

extends AbstractTree

{

protected Object key;

protected int degree;

protected NaryTree[] subtree;

public boolean isEmpty ()

{ return key == null; }

}

Page 59: Árvores

59

Métodos getKey e attachKey

public Object getKey () {

if (isEmpty ()) throw new InvalidOperationException ();return key;

}

public void attachKey (Object object) {

if (!isEmpty ()) throw new InvalidOperationException ();key = object;subtree = new NaryTree[degree];for (int i = 0; i < degree; ++i) subtree [i] = new NaryTree (degree);

}

Page 60: Árvores

60

Método detachKey

public Object detachKey () {if (!isLeaf ()) throw new InvalidOperationException ();Object result = key;key = null;subtree = null;return result;

}

Page 61: Árvores

61

Métodos getKey, attachKey e detachKey

getKey é um método de acesso que retorna o objeto contido na raiz da árvore. attachKey insere um objeto na raiz de uma árvore N-aria. São criadas N sub árvores vaziasdetachKey remove o objeto da raiz de uma árvore. Para manter a definição de árvore N-aria só se pode remover a raiz de um nó folha.

Page 62: Árvores

62

Métodos getSubTree e attachSubTree

// pgm09_19.txt public Tree getSubtree (int i) {

if (isEmpty ()) throw new InvalidOperationException ();return subtree [i];

}

public void attachSubtree (int i, NaryTree t) {

if (isEmpty () || !subtree [i].isEmpty ()) throw new InvalidOperationException ();subtree [i] = t;

}

Page 63: Árvores

63

Método detachSubTree

NaryTree detachSubtree (int i) {if (isEmpty ()) throw new InvalidOperationException ();NaryTree result = subtree [i];subtree [i] = new NaryTree (degree);return result;

}

Page 64: Árvores

64

Árvores Binárias

Page 65: Árvores

65

Classe BinaryTree

// pgm09_20.txtpublic class BinaryTree extends AbstractTree{ protected Object key; protected BinaryTree left; protected BinaryTree right;

// ...}

Page 66: Árvores

66

Construtores de BinaryTree (1)

// pgm09_21.txtpublic class BinaryTree extends AbstractTree{ protected Object key; protected BinaryTree left; protected BinaryTree right;

public BinaryTree (Object key, BinaryTree left, BinaryTree right)

{this.key = key;this.left = left;this.right = right;

}

Page 67: Árvores

67

Construtores de BinaryTree (2)

public BinaryTree (){ this (null, null, null); }

public BinaryTree (Object key){ this (key, new BinaryTree (), new BinaryTree ()); }

// ... }

Page 68: Árvores

68

Método Purge// pgm09_22.txtpublic class BinaryTree extends AbstractTree{ protected Object key; protected BinaryTree left; protected BinaryTree right;

public void purge () {

key = null;left = null;right = null;

} // ...}

Page 69: Árvores

69

Travessia de árvores binárias//pgm09_23.txtpublic class BinaryTree extends AbstractTree{ protected Object key; protected BinaryTree left; protected BinaryTree right;

public void depthFirstTraversal (PrePostVisitor visitor) {

if (!isEmpty ()){ visitor.preVisit (key); left.depthFirstTraversal (visitor); visitor.inVisit (key); right.depthFirstTraversal (visitor); visitor.postVisit (key);}

}}

Page 70: Árvores

70

Comparação de árvores

Page 71: Árvores

71

Comparação de árvores protected int compareTo (Comparable object) {

BinaryTree arg = (BinaryTree) object;if (isEmpty ()) return arg.isEmpty () ? 0 : -1;else if (arg.isEmpty ()) return 1;else{ int result = ((Comparable) getKey ()).compare ((Comparable) arg.getKey ()); if (result == 0)result = getLeft ().compareTo (arg.getLeft ()); if (result == 0)result = getRight ().compareTo (arg.getRight ()); return result;}

}

Page 72: Árvores

72

Classe AbstractTree

// pgm09_09.txtpublic abstract class AbstractTree extends AbstractContainer implements Tree{ public void accept (Visitor visitor){ depthFirstTraversal (new PreOrder (visitor)); }

// ...}

Page 73: Árvores

73

DFT (depthFirstTraversal)

// pgm09_23.txtpublic class BinaryTree extends AbstractTree{ protected Object key; protected BinaryTree left; protected BinaryTree right;

public void depthFirstTraversal (PrePostVisitor visitor) {

if (!isEmpty ()){ visitor.preVisit (key); left.depthFirstTraversal (visitor); visitor.inVisit (key); right.depthFirstTraversal (visitor); visitor.postVisit (key);}

}}

Page 74: Árvores

74

Implementação C++

Page 75: Árvores

75

Definição da Classe Tree

// pgm09_01.cppclass Tree : public virtual Container{

class Iter;public:

virtual Object& Key () const = 0;virtual Tree& Subtree (unsigned int) const = 0;virtual bool IsEmpty () const = 0;virtual bool IsLeaf () const = 0;virtual unsigned int Degree () const = 0;virtual int Height () const;virtual void DepthFirstTraversal (PrePostVisitor&) const;virtual void BreadthFirstTraversal (Visitor&) const;void Accept (Visitor&) const;

};

Page 76: Árvores

76

Definições da Função Membro Traversal da Classe Tree

// pgm09_02.cppvoid Tree::DepthFirstTraversal ( PrePostVisitor&

visitor) const{

if(visitor.IsDone ())return;

if(!IsEmpty ()){

visitor.PreVisit (Key ());for(unsigned int i = 0; i < Degree (); ++i)

Subtree (i).DepthFirstTraversal (visitor);

visitor.PostVisit (Key ());}

}

Page 77: Árvores

77

Definições das Classes PrePostVisitor e PreOrder

// pgm09_03.cppclass PrePostVisitor : public Visitor{public:

virtual void PreVisit (Object&) {}virtual void Visit (Object&) {}virtual void PostVisit (Object&) {}

};

class PreOrder : public PrePostVisitor{

Visitor& visitor;public:

PreOrder (Visitor& v) : visitor (v) {}void PreVisit (Object& object){ visitor.Visit (object); }

};

Page 78: Árvores

78

Definições das Classes InOrder e PostOrderclass InOrder : public PrePostVisitor{

Visitor& visitor;public:

InOrder (Visitor& v) : visitor (v) {}void Visit (Object& object){ visitor.Visit (object); }

};

class PostOrder : public PrePostVisitor{

Visitor& visitor;public:

PostOrder (Visitor& v) : visitor (v) {}void PostVisit (Object& object){ visitor.Visit (object); }

};

Page 79: Árvores

79

Definição da Função Membro BreadthFirstTraversal da Classe Tree// pgm09_04.cppvoid Tree::BreadthFirstTraversal (Visitor& visitor) const{

Queue& queue = *new QueueAsLinkedList ();queue.RescindOwnership ();if(!IsEmpty ())

queue.Enqueue(const_cast<Tree&> (*this));while(!queue.IsEmpty() && !visitor.IsDone()) {

Tree const& head = dynamic_cast<Tree const &>(queue.Dequeue ());

visitor.Visit(head.Key ());for(unsigned int i = 0; i < head.Degree (); ++i) {

Tree& child = head.Subtree(i);if(!child.IsEmpty ())

queue.Enqueue (child);}

}delete &queue;}

Page 80: Árvores

80

Definição da Função Membro Accept da Classe Tree

// pgm09_05.cpp

void Tree::Accept (Visitor& visitor) const

{ DepthFirstTraversal (PreOrder (visitor)); }

Page 81: Árvores

81

Definição da Classe Tree::Iter

// pgm09_06.cpp

class Tree::Iter : public Iterator

{

Tree const& tree;

Stack& stack;

public:

Iter(Tree const&);

~Iter();

void Reset();

bool IsDone() const;

Object& operator * () const;

void operator ++ ();

};

Page 82: Árvores

82

Definições da Função Membro Reset e do Construtor da Classe Tree::Iter

// pgm09_07.cppTree::Iter::Iter (Tree const& _tree) :

tree (_tree), stack (*new StackAsLinkedList ()){

stack.RescindOwnership();Reset();

}Tree::Iter::~Iter()

{ delete &stack; }void Tree::Iter::Reset(){

stack.Purge();if(!tree.IsEmpty ())stack.Push(const_cast<Tree&> (tree));

}

Page 83: Árvores

83

Definições das Funções Membro Operador da Classe Tree::Iter (1)

// pgm09_08.cppbool Tree::Iter::IsDone() const

{ return stack.IsEmpty(); }Object& Tree::Iter::operator * () const{

if(!stack.IsEmpty ()){

Tree const& top = dynamic_cast<Tree const&> (stack.Top ());

return top.Key ();}else

return NullObject::Instance ();}

Page 84: Árvores

84

Definições da Função Membro Operador da Classe Tree::Iter (2)

void Tree::Iter::operator ++ (){

if(!stack.IsEmpty ()){

Tree const& top = dynamic_cast<Tree const&> (stack.Pop ());

for(int i = top.Degree () - 1; i >= 0; --i){

Tree& subtree = top.Subtree (i);if(!subtree.IsEmpty ())

stack.Push (subtree);}

}}

Page 85: Árvores

85

Definição da Classe GeneralTree// pgm09_09.cppclass GeneralTree : public Tree{protected:

Object* key;unsigned int degree;LinkedList<GeneralTree*> list;

public:GeneralTree(Object&);~GeneralTree();Object& Key() const;GeneralTree& Subtree(unsigned int) const;virtual void AttachSubtree(GeneralTree&);virtual GeneralTree& DetachSubtree(GeneralTree&);// ...

};

Page 86: Árvores

86

Definições da Função Membro Purge, do Construtor e do Destrutor da Classe GeneralTree

// pgm09_10.cppGeneralTree::GeneralTree (Object& _key) :

key (&_key), degree (0), list(){}

void GeneralTree::Purge(){

ListElement<GeneralTree*> const* ptr;if(IsOwner ())

delete key;for(ptr = list.Head(); ptr != 0; ptr = ptr->Next())

delete ptr->Datum();key = 0;list.Purge();

}GeneralTree::~GeneralTree()

{ Purge (); }

Page 87: Árvores

87

Definições das Funções Membro Key, Subtree, AttachSubtree e DetachSubtree da Classe GeneralTree (1)

// pgm09_11.cppObject& GeneralTree::Key() const

{ return *key; }GeneralTree& GeneralTree::Subtree(unsigned int i) const{

if(i >= degree)throw out_of_range("invalid subtree index");

unsigned int j = 0;ListElement<GeneralTree*> const* ptr = list.Head();while(j < i && ptr != 0){

++j;ptr = ptr->Next();

}if(ptr == 0)

throw logic_error("should never happen");return *ptr->Datum();

}

Page 88: Árvores

88

Definições das Funções Membro Key, Subtree, AttachSubtree e DetachSubtree da Classe GeneralTree (2)

// pgm09_11.cpp (Continuação)

void GeneralTree::AttachSubtree(GeneralTree& t){

list.Append (&t);++degree;

}

GeneralTree& GeneralTree::DetachSubtree(GeneralTree& t){

list.Extract (&t);--degree;return t;

}

Page 89: Árvores

89

Definição da Classe NaryTree// pgm09_12.cppclass NaryTree : public Tree{protected:

Object* key;unsigned int const degree;Array<NaryTree*> subtree;

public:NaryTree(unsigned int);NaryTree(unsigned int, Object&);~NaryTree();Object& Key() const;NaryTree& Subtree(unsigned int) const;virtual void AttachKey(Object&);virtual Object& DetachKey();virtual void AttachSubtree(unsigned int, NaryTree&);virtual NaryTree& DetachSubtree(unsigned int);// ...

};

Page 90: Árvores

90

Definições dos Construtores da Classe NarryTree

// pgm09_13.cppNaryTree::NaryTree(unsigned int _degree) :

key (0),degree(_degree),subtree(0){}

NaryTree::NaryTree(unsigned int _degree, Object& _key):key(&_key),degree(_degree),subtree(_degree)

{for(unsigned int i = 0; i < degree; ++i)

subtree [i] = new NaryTree(degree);}

Page 91: Árvores

91

Definições das Funções Membro IsEmpty, Key e AttachKey da Classe NaryTree

// pgm09_14.cppbool NaryTree::IsEmpty() const

{ return key == 0; }Object& NaryTree::Key() const{

if(IsEmpty ())throw domain_error("invalid operation");

return *key;}void NaryTree::AttachKey(Object& object){

if(!IsEmpty ())throw domain_error("invalid operation");

key = &object;subtree.SetLength(degree);for(unsigned int i = 0; i < degree; ++i)

subtree[i] = new NaryTree(degree);}

Page 92: Árvores

92

Definições da Função Membro DetachKey da Classe NaryTree

Object& NaryTree::DetachKey(){

if(!IsLeaf ())throw domain_error("invalid operation");

Object& result = *key;key = 0;for(unsigned int i = 0; i < degree; ++i)

delete subtree[i];subtree.SetLength(0);return result;

}

Page 93: Árvores

93

Definições das Funções Membro Subtree e AttachSubtree da Classe NaryTree

// pgm09_15.cppNaryTree& NaryTree::Subtree(unsigned int i) const{

if(IsEmpty ())throw domain_error("invalid operation");

return *subtree[i];}

void NaryTree::AttachSubtree(unsigned int i, NaryTree& t){

if(IsEmpty ())throw domain_error("invalid operation");

if(!subtree [i]->IsEmpty ())throw domain_error("non-empty subtree present");

delete subtree[i];subtree[i] = &t;

}

Page 94: Árvores

94

Definições da Função Membro DetachSubtree da Classe NaryTree

// pgm09_15.cpp (Continuação)

NaryTree& NaryTree::DetachSubtree(unsigned int i){

if(IsEmpty ())throw domain_error("invalid operation");

NaryTree& result = *subtree[i];subtree[i] = new NaryTree(degree);return result;

}

Page 95: Árvores

95

Definição da Classe BinaryTree (1)

// pgm09_16.cppclass BinaryTree : public virtual Tree{protected:Object* key;

BinaryTree* left;BinaryTree* right;

public:BinaryTree();BinaryTree(Object&);~BinaryTree();

Page 96: Árvores

96

Definição da Classe BinaryTree (2)

Object& Key() const;virtual void AttachKey(Object&);virtual Object& DetachKey();virtual BinaryTree& Left() const;virtual BinaryTree& Right() const;virtual void AttachLeft(BinaryTree&);virtual void AttachRight(BinaryTree&);virtual BinaryTree& DetachLeft();virtual BinaryTree& DetachRight();// ...

};

Page 97: Árvores

97

Definição dos Construtores da Classe BinaryTree

// pgm09_17.cpp

BinaryTree::BinaryTree() :

key(0),

left(0),

right(0)

{}

BinaryTree::BinaryTree(Object& _key) :

key(&_key),

left(new BinaryTree ()),

right(new BinaryTree ())

{}

Page 98: Árvores

98

Definições da Função Membro Purge e do Destrutor da Classe BinaryTree

// pgm09_18.cppvoid BinaryTree::Purge(){

if(!IsEmpty ()){

if(IsOwner ())delete key;

delete left;delete right;key = 0;left = 0;right = 0;

}}BinaryTree::~BinaryTree()

{ Purge (); }

Page 99: Árvores

99

Definição da Função Membro DepthFirstTraversal da Classe BinaryTree

// pgm09_19.cppvoid BinaryTree::DepthFirstTraversal( PrePostVisitor&

visitor) const{

if(visitor.IsDone ())return;

if(!IsEmpty ()){

visitor.PreVisit (*key);left->DepthFirstTraversal(visitor);visitor.Visit(*key);right->DepthFirstTraversal(visitor);visitor.PostVisit(*key);

}}

Page 100: Árvores

100

Definição da Função Membro CompareTo da Classe BinaryTree// pgm09_20.cppint BinaryTree::CompareTo(Object const& object) const {

BinaryTree const& arg = dynamic_cast<BinaryTreeconst&> (object);

if(IsEmpty ())return arg.IsEmpty() ? 0 : -1;

else if(arg.IsEmpty ())

return 1; else { int result = Key().Compare(arg.Key ());

if(result == 0)result = Left().CompareTo(arg.Left ());

if(result == 0)result = Right().CompareTo(arg.Right ());

return result; }

}

Page 101: Árvores

101

REPRESENTAÇÃO DE ÁRVORES POR ÁRVORES BINÁRIAS

Page 102: Árvores

102

REPRESENTAÇÃO DE ÁRVORES POR

ÁRVORES BINÁRIAS

Uma das maneiras mais eficientes de representar árvores em linguagens de programação consiste na consideração dos filhos de cada nó por meio de uma lista encadeada. Nessa representação os nós são do tipo

Page 103: Árvores

103

Representação de árvores por árvores binárias

Page 104: Árvores

104

Representação de árvores por árvores binárias

Fazendo uma analogia com árvores binárias associando o conceito de son com o de left e o conceito de next com o de right pode-se obter uma árvore binária equivalente a uma árvore qualquer. Graficamente o que se faz é dar uma rotação horária de /4 rd à representação

Page 105: Árvores

105

Algoritmo de representação de uma árvore

por uma árvore binária equivalente

i) Reproduz-se a raiz da árvore original para a raiz da árvore binária equivalente;ii ) Para cada nó na árvore binária equivalente considerar como filho mais velho o filho mais velho, ou único, na árvore original. Considerar como filho mais novo, na árvore binária equivalente, o irmão que sucede imediatamente o nó na árvore original.

Page 106: Árvores

106

Representação de uma árvore por uma árvore binária equivalente

Quando se utiliza uma árvore binária equivalente a uma árvore qualquer, a correspondência entre percursos nestas árvores é a seguinte:O percurso pré-fixo da árvore original coincide com o percurso pré-fixo da árvore binária transformada. O percurso pós-fixo na árvore original coincide com o percurso infixo na árvore binária equivalente. O percurso infixo não tem sentido senão em árvores binárias e, portanto, não existe na árvore original.

Page 107: Árvores

107

Árvores binárias equivalentes

Page 108: Árvores

108

Árvores Binárias equivalentes

Page 109: Árvores

109

Árvores Binárias equivalentes