Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Binary Tree Traversals Binary Tree Traversal classification Tree traversal animations DepthFirst traversal abstraction Accept method of AbstractTree.

Similar presentations


Presentation on theme: "1 Binary Tree Traversals Binary Tree Traversal classification Tree traversal animations DepthFirst traversal abstraction Accept method of AbstractTree."— Presentation transcript:

1 1 Binary Tree Traversals Binary Tree Traversal classification Tree traversal animations DepthFirst traversal abstraction Accept method of AbstractTree class Tree enumeration

2 2 Tree Traversal (Definition) The process of systematically visiting all the nodes in a tree and performing some computation at each node in the tree is called a tree traversal. There are two methods in which to traverse a tree: 1.Depth-First Traversal. 2.Breadth-First Traversal.

3 3 Depth-First Traversal CODEEach NodeName 1 public void preorderTraversal(){ 2 if(! isEmpty() ){ 3 System.out.print(getKey() + " "); 4 getLeftBST().preorderTraversal(); 5 getRightBST().preorderTraversal(); 6 } 7} Visit the node Visit the left subtree, if any. Visit the right subtree, if any. Preorder (N-L-R) 1 public void inorderTraversal(){ 2 if(! isEmpty() ){ 3 getLeftBST().inorderTraversal(); 4 System.out.print(getKey() + " " ); 5 getRightBST().inorderTraversal(); 6 } 7 } Visit the left subtree, if any. Visit the node Visit the right subtree, if any. Inorder (L-N-R) 1 public void postorderTraversal( ) { 2 if( ! isEmpty( ) ) { 3 getLeftBST( ).postorderTraversal( ) ; 4 getRightBST( ).postorderTraversal( ); 5 System.out.print(getKey( ) + " ") ; 6 } 7 } Visit the left subtree, if any. Visit the right subtree, if any. Visit the node Postorder (L-R-N)

4 4 Breadth-First Traversal The AbstractTree class breadthFirstTraversal method: 1 public void breadthFirstTraversal(Visitor visitor){ 2 Queue queue = new QueueAsLinkedList() ; 3 if(! isEmpty()) 4 queue.enqueue(this) ; 5 while(! queue.isEmpty() && ! visitor.isDone()) { 6 Tree head = (Tree) queue.dequeue() ; 7 visitor.visit(head.getKey()) ; 8 for(int i = 0; i < head.getDegree(); i++) 8 { 9 Tree child = head.getSubtree(i) ; 10 if(! child.isEmpty()) 11 queue.enqueue(child) ; 12 } 13 } 14 }

5 5 Preorder Traversal H D B A C E G I KMO N L J F OMNKIJLGEFCABDH N-L-R

6 6 Inorder Traversal H D B A C E G I KMO N L J F L-N-R ONMLKJIHGFEDCBA

7 7 Postorder Traversal H D B A C E G I KMO N L J F L-R-N HLNOMJKIDFGEBCA

8 8 Breadth-First Traversal H D B A C E G I KMO N L J F OMKIGECANJFBLDH

9 9 Depth-First Traversal Abstraction Preorder, inorder, and postorder traversals are special cases of depth-first traversal. Rather than implement each of these traversals directly, as we have done in page 3, we make use of a design pattern, called adapter, that allows the three traversals to be implemented as the following single method: 1 public class BinaryTree extends AbstractTree{ 2 protected Object key ; 3 protected BinaryTree left ; protected BinaryTree right ; 4 public void depthFirstTraversal(PrePostVisitor visitor){ 5 if(! isEmpty()){ 6 visitor.preVisit(key) ; 7 left.depthFirstTraversal(visitor) ; 8 visitor.inVisit(key) ; 9 right.depthFirstTraversal(visitor) ; 10 visitor.postVisit(key) ; } 11 } 12 //... 13 }

10 10 Breadth-First Traversal Abstraction (Contd.) The depthFirstTraversal method takes as its argument any object that implements the PrePostVisitor interface: 1 public interface PrePostVisitor{ 2 void preVisit(Object object) ; 3 void inVisit(Object object) ; 4 void postVisit(Object object) ; 4 boolean isDone() ; 5} As each node is visited in a traversal, the preVisit, inVisit, and postVisit methods of the visitor are invoked on the object contained in that node. Recall that to print all objects in a container, we can create a PrintingVisitor that prints every object it visits: 1 public class PrintingVisitor implements Visitor{ 2 public void visit(Object object){ 4 System.out.println(object) ; } //... 5 //...} 6 //... 7 Container c = new SomeContainer( ) ; 8 c.accept(new PrintingVisitor( )) ;

11 11 Breadth-First Traversal Abstraction (Contd.) Unfortunately a PrintingVisitor instance cannot be passed to the depthFirstTraversal method: The depthFirstTraversal method expects an object that implements the PrePostVisitor interface, whereas the PrintingVisitor class implements the Visitor interface. The solution is to use an adapter. An adapter converts the interface provided by one class to the interface required by another class. For example, if we want a preorder traversal, then the call to the preVisit (made by the depthFirstTraversal) should be mapped to the visit method (provided by the PrintingVisitor). Similarly, a postorder traversal is obtained by mapping postVisit to visit. An inorder traversal is obtained by mapping inVisit to visit.

12 12 AbstractPrePostVisitor class The AbstractPrePostVisitor class defined below provides default implementations for the preVisit, inVisit, and postVisit methods: 1 public abstract class AbstractPrePostVisitor implements PrePostVisitor 2 { 3 public void preVisit(Object object) { } 4 public void inVisit(Object object) { } 5 public void postVisit(Object object) { } 6 public boolean isDone() { return false;} 7 } Each of the three adapter classes we will discuss: PreOrder, InOrder, and PostOrder: (a) Extends the AbstractPrePostVisitor class. (b) Has a single, protected, instance variable that implements the Visitor interface. (c) Overrides the isDone method and only one of the three methods, preVisit, inVisit, and postVisit, inherited from the AbstractPrePostVisitor class.

13 13 Adaptor classes 1 public class PreOrder extends AbstractPrePostVisitor{ 2 protected Visitor visitor ; 3 public PreOrder(Visitor visitor) 4 { this.visitor = visitor ; } 5 public void preVisit(Object object) 6 { visitor.visit(object) ; } 7 public boolean isDone(){ 8 return visitor.isDone() ; } 9 } 1 public class InOrder extends AbstractPrePostVisitor{ 2 protected Visitor visitor ; 3 public InOrder(Visitor visitor) 4 { this.visitor = visitor ; } 5 public void inVisit(Object object) 6 { visitor.visit(object) ; } 7 public boolean isDone() 9{ return visitor.isDone() ; } 8 }

14 14 Adaptor classes (Contd.) 1 public class PostOrder extends AbstractPrePostVisitor{ 2 protected Visitor visitor ; 3 public PostOrder(Visitor visitor) 4 {this.visitor = visitor ; } 5 public void postVisit(Object object) 6 { visitor.visit(object) ; } 7 public boolean isDone() 9{ return visitor.isDone() ; } 10 } Each adapter class provides a different interface mapping. Note that an adapter class provides no functionality of its own, it simply forwards method calls to the visitor instance as required. The following code illustrates how these adapters are used: Visitor v = new PrintingVisitor() ; BinaryTree t = new BinaryTree() ; //... t.depthFirstTraversal(new PreOrder(v)) ; t. depthFirstTraversal(new InOrder(v)) ; t.depthFirstTraversal(new PostOrder(v)) ;

15 15 The default accept method of the AbstractTree class Usually the accept method of a container is allowed to visit the elements of the container in any order. A tree traversal visits the nodes in either preoder or postorder and for Binary trees inorder traversal is also possible. Hence, the AbstractTree class provides a default accept method that does a preorder traversal: 1 public void accept(Visitor visitor) 2 { 3 depthFirstTraversal(new Preorder(visitor)) ; 4 }

16 16 The Default Tree Enumeration The implementation of a tree enumeration must do a tree traversal. Hence, the AbstractTree class provides a default tree enumeration that does a preorder traversal. The enumeration is implemented as an inner class: 1 protected class TreeEnumeration implements Enumeration{ 2 protected Stack stack; 3 public TreeEnumeration(){ 4 stack = new StackAsLinkedList() ; 5 if(! isEmpty()) stack.push(AbstractTree.this) ; 6 } 7 public boolean hasMoreElements() { return ! stack.isEmpty(); } 8 public Object nextElement(){ 9 if(stack.isEmpty()) throw new NoSuchElementException() ; 10 Tree top = (Tree) stack.pop() ; 11 for(int i = top.getDegree() - 1 ; i >= 0 ; i--){ 12 Tree subtree = (Tree) top.getSubtree(i) ; 13 if(! subtree.isEmpty()) stack.push(subtree) ; 14 } 15 return top.getKey( ); } 16 }

17 17 Using a Tree Enumeration The getEnumeration method of the AbstractTree class returns a new instance of the TreeEnumeration inner class each time it is called: 1 public Enumeration getEnumeration( ) 2 return new TreeEnumeration( ) ; 3} The following program fragment shows how to use a tree numeration: 1 Tree tree = new BinaryTree() ; 2 //... 3 Enumeration e = tree.getEnumeration() ; 4 while(e.hasMoreElements() 5 { 6 Object obj = e.nextElement() ; 7 System.out.print(obj + " ") ; 8 }


Download ppt "1 Binary Tree Traversals Binary Tree Traversal classification Tree traversal animations DepthFirst traversal abstraction Accept method of AbstractTree."

Similar presentations


Ads by Google