A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

1 Árvores. 2 Definição Definiçã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,

Apresentações semelhantes


Apresentação em tema: "1 Árvores. 2 Definição Definiçã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,"— Transcrição da apresentação:

1 1 Árvores

2 2 Definição Definiçã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, T 1, T 2,..., T n, cada um dos quais sendo uma árvore. É usual adotar para a árvore T a notação.

3 3 Nomenclatura Seja uma árvore com n 0 Grau de um nó é o número de sub-árvores do nó Folha é um nó de grau zero As raízes r i das sub-árvores T i são filhas de r A raiz r da árvore T é pai das raízes r i Raízes r i e r j de árvores distintas T i e T j são irmãs

4 4 Nomenclatura Nível ou profundidade de um nó r i de uma árvore T é o comprimento do caminho entre a raiz e o nó r i 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 folha Altura de uma árvore é a altura do nó raiz O pai de um nó é seu ancestral e o pai de seu pai também O filho de um nó é seu descendente e o filho de seu filho também Ordem de um nó é o grau do nó Ordem de uma árvore é a ordem de seu nó de maior ordem

5 5 Nomenclatura Níveis em versão Horowitz

6 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))))

7 7 Outras representações de árvores

8 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

9 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 N 0 sub conjuntos, T 0,T 1,..., T N-1, cada qual sendo uma árvore N-aria tal que

10 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 T R. A árvore T L é chamada árvore da esquerda de T, e a árvore T R é chamada árvore da direita de T.

11 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)

12 12 Backtracking Backtracking é 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 posteriores Para 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ção Se 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 diante Backtracking termina quando não mais existem soluções para o primeiro sub problema.

13 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 alternativo breadth 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.

14 14 BFT (Breadth-First Traversal) Enquanto a travessia em profundidade (DFT) é definida recursivamente a travessia em largura é melhor compreendida como uma travessia não recursiva A 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

15 15 Árvores Genéricas

16 16 Árvores Genéricas

17 17 Árvores Binárias

18 18 Árvores Binárias

19 19 Árvores binárias completas e incompletas

20 20 Implementação de árvores binárias por arrays

21 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 + 1 n (caso o nó inicial seja 0 em vez de 1 o valor será 2*i+2) Caso contrário este filho não existe

22 22 Implementação de árvores binárias por encadeamento Os nós das árvores binárias podem ser representados da forma

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

24 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

25 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.

26 26 Caminhamento ou percurso sobre árvores binárias Percurso ou notação pré-fixa: ABDHIECFG Percurso ou notação infixa: HDIBEAFCG Percurso ou notação pós-fixa: HIDEBFGCA

27 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.

28 28 Notação Decimal de Dewey

29 29 Implementação Java

30 30 Framework de Árvores

31 31 Interface Tree //pgm09_01.txt public 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); }

32 32 Métodos da Interface Tree getKey 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ó.

33 33 Método depthFirstTraversal de AbstractTree // pgm09_02.txt public 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 ()); } //... }

34 34 Interface PrePostVisitor //pgm09_03.txt public interface PrePostVisitor { void preVisit (Object object); void inVisit (Object object); void postVisit (Object object); boolean isDone (); }

35 35 Classe Abstrata AbstractPrePostVisitor //pgm09_04.txt public 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; } }

36 36 Classe PreOrder // //pgm09_05.txt public 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 (); } }

37 37 Classe InOrder // //pgm09_06.txt public 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 (); } }

38 38 Classe PostOrder // //pgm09_07.txt public 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 (); } }

39 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));

40 40 Implementação de BFT (1) // pgm09_08.txt public abstract class AbstractTree extends AbstractContainer implements Tree { public void breadthFirstTraversal (Visitor visitor) { Queue queue = new QueueAsLinkedList (); if (!isEmpty ()) queue.enqueue (this); }

41 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); }

42 42 Método accept // pgm09_09.txt public 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

43 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); }

44 44 Classe interna TreeEnumeration // pgm09_10.txt public abstract class AbstractTree extends AbstractContainer implements Tree { public Enumeration getEnumeration () { return new TreeEnumeration (); } protected class TreeEnumeration implements Enumeration { protected Stack stack; //... } //... }

45 45 Construtor de TreeEnumeration // pgm09_11.txt public 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

46 46 Método hasMoreElements da Classe AbstractTree // pgm09_12.txt public abstract class AbstractTree extends AbstractContainer implements Tree { protected class TreeEnumeration implements Enumeration { public boolean hasMoreElements () { return !stack.isEmpty (); }

47 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)

48 48 Árvores Genéricas

49 49 Classe GeneralTree // //pgm09_13.txt public class GeneralTree extends AbstractTree { protected Object key; protected int degree; protected LinkedList list; //... }

50 50 Métodos Construtor e Purge de GeneralTree // pgm09_14.txt public 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; }

51 51 Método getSubtree da Classe Generaltree // pgm09_15.txt public class GeneralTree extends AbstractTree { protected Object key; protected int degree; protected LinkedList list; public Object getKey () { return key; }

52 52 Método getSubtree da Classe Generaltree public Tree getSubtree (int i) { if (i = degree) throw new IndexOutOfBoundsException (); LinkedList.Element ptr = list.getHead (); for (int j = 0; j < i; ++j) ptr = ptr.getNext (); return (GeneralTree) ptr.getDatum (); } //... }

53 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; }

54 54 Árvores N-árias

55 55 Classe NaryTree // //pgm09_16.txt public class NaryTree extends AbstractTree { protected Object key; protected int degree; protected NaryTree[] subtree; //... }

56 56 Construtores de NaryTree (1) // pgm09_17.txt public class NaryTree extends AbstractTree { protected Object key; protected int degree; protected NaryTree[] subtree; public NaryTree (int degree) { key = null; this.degree = degree; subtree = null; }

57 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); } //... }

58 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; } }

59 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); }

60 60 Método detachKey public Object detachKey () { if (!isLeaf ()) throw new InvalidOperationException (); Object result = key; key = null; subtree = null; return result ; }

61 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 vazias detachKey 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.

62 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; }

63 63 Método detachSubTree NaryTree detachSubtree (int i) { if (isEmpty ()) throw new InvalidOperationException (); NaryTree result = subtree [i]; subtree [i] = new NaryTree (degree); return result; }

64 64 Árvores Binárias

65 65 Classe BinaryTree // pgm09_20.txt public class BinaryTree extends AbstractTree { protected Object key; protected BinaryTree left; protected BinaryTree right; //... }

66 66 Construtores de BinaryTree (1) // pgm09_21.txt public 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; }

67 67 Construtores de BinaryTree (2) public BinaryTree () { this (null, null, null); } public BinaryTree (Object key) { this (key, new BinaryTree (), new BinaryTree ()); } //... }

68 68 Método Purge // pgm09_22.txt public class BinaryTree extends AbstractTree { protected Object key; protected BinaryTree left; protected BinaryTree right; public void purge () { key = null; left = null; right = null; } //... }

69 69 Travessia de árvores binárias //pgm09_23.txt public 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); }

70 70 Comparação de árvores

71 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; }

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

73 73 DFT (depthFirstTraversal) // pgm09_23.txt public 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); }

74 74 Implementação C++

75 75 Definição da Classe Tree // pgm09_01.cpp class 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; };

76 76 Definições da Função Membro Traversal da Classe Tree // pgm09_02.cpp void 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 ()); }

77 77 Definições das Classes PrePostVisitor e PreOrder // pgm09_03.cpp class 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); } };

78 78 Definições das Classes InOrder e PostOrder class 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); } };

79 79 Definição da Função Membro BreadthFirstTraversal da Classe Tree // pgm09_04.cpp void Tree::BreadthFirstTraversal (Visitor& visitor) const { Queue& queue = *new QueueAsLinkedList (); queue.RescindOwnership (); if(!IsEmpty ()) queue.Enqueue(const_cast (*this)); while(!queue.IsEmpty() && !visitor.IsDone()) { Tree const& head = dynamic_cast (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; }

80 80 Definição da Função Membro Accept da Classe Tree // pgm09_05.cpp void Tree::Accept (Visitor& visitor) const { DepthFirstTraversal (PreOrder (visitor)); }

81 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 ++ (); };

82 82 Definições da Função Membro Reset e do Construtor da Classe Tree::Iter // pgm09_07.cpp Tree::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)); }

83 83 Definições das Funções Membro Operador da Classe Tree::Iter (1) // pgm09_08.cpp bool Tree::Iter::IsDone() const { return stack.IsEmpty(); } Object& Tree::Iter::operator * () const { if(!stack.IsEmpty ()) { Tree const& top = dynamic_cast (stack.Top ()); return top.Key (); } else return NullObject::Instance (); }

84 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 (stack.Pop ()); for(int i = top.Degree () - 1; i >= 0; --i) { Tree& subtree = top.Subtree (i); if(!subtree.IsEmpty ()) stack.Push (subtree); }

85 85 Definição da Classe GeneralTree // pgm09_09.cpp class GeneralTree : public Tree { protected: Object* key; unsigned int degree; LinkedList list; public: GeneralTree(Object&); ~GeneralTree(); Object& Key() const; GeneralTree& Subtree(unsigned int) const; virtual void AttachSubtree(GeneralTree&); virtual GeneralTree& DetachSubtree(GeneralTree&); //... };

86 86 Definições da Função Membro Purge, do Construtor e do Destrutor da Classe GeneralTree // pgm09_10.cpp GeneralTree::GeneralTree (Object& _key) : key (&_key), degree (0), list() {} void GeneralTree::Purge() { ListElement 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 (); }

87 87 Definições das Funções Membro Key, Subtree, AttachSubtree e DetachSubtree da Classe GeneralTree (1) // pgm09_11.cpp Object& 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 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(); }

88 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; }

89 89 Definição da Classe NaryTree // pgm09_12.cpp class NaryTree : public Tree { protected: Object* key; unsigned int const degree; Array 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); //... };

90 90 Definições dos Construtores da Classe NarryTree // pgm09_13.cpp NaryTree::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); }

91 91 Definições das Funções Membro IsEmpty, Key e AttachKey da Classe NaryTree // pgm09_14.cpp bool 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); }

92 92 Definições da Função Membro D etachKey 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; }

93 93 Definições das Funções Membro Subtree e AttachSubtree da Classe NaryTree // pgm09_15.cpp NaryTree& 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; }

94 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; }

95 95 Definição da Classe BinaryTree (1) // pgm09_16.cpp class BinaryTree : public virtual Tree { protected: Object* key; BinaryTree* left; BinaryTree* right; public: BinaryTree(); BinaryTree(Object&); ~BinaryTree();

96 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(); //... };

97 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 ()) {}

98 98 Definições da Função Membro Purge e do Destrutor da Classe BinaryTree // pgm09_18.cpp void BinaryTree::Purge() { if(!IsEmpty ()) { if(IsOwner ()) delete key; delete left; delete right; key = 0; left = 0; right = 0; } BinaryTree::~BinaryTree() { Purge (); }

99 99 Definição da Função Membro DepthFirstTraversal da Classe BinaryTree // pgm09_19.cpp void 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); }

100 100 Definição da Função Membro CompareTo da Classe BinaryTree // pgm09_20.cpp int BinaryTree::CompareTo(Object const& object) const { BinaryTree const& arg = dynamic_cast (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; }

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

102 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

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

104 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

105 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.

106 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.

107 107 Árvores binárias equivalentes

108 108 Árvores Binárias equivalentes

109 109 Árvores Binárias equivalentes


Carregar ppt "1 Árvores. 2 Definição Definiçã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,"

Apresentações semelhantes


Anúncios Google