In this lab you will implement Iterator classes for performing traversals of a binary tree. The traversals are the same ones that you implemented in Lab 9: pre order, post order, in order, and level order. However, rather than using a recursive method to perform each traversal, you will implement several classes implementing the Iterator interface to perform the traversals.
Using an iterator to perform pre-, post-, and in-order traversals is more complicated than using a recursive method, because you can't take advantage of the method call stack to keep track of where you've been. Instead you must use an explicit Stack object. Fortunately, by implementing a single general binary tree iterator in the right way, it is trivial to implement all three of these traversals without recursion.
Here is an example of a general binary tree traversal:
The dotted blue lines show the progress of the traversal. Observe that the node marked with the "B" is visited three times in the course of the traversal:
Another way to visualize what is happening is this:
So, to implement the general binary tree traversal algorithm, we just need to keep track of the stack of nodes that are currently in progress, and how many times we have visited each node in the stack. The process starts by pushing the root node onto the stack and marking it as having been visited 0 times.
Here is a complete history of what the stack looks like at each step of the traversal. The items on the stack are nodes and the number of times each node has been visited by the general traversal.
Note that in this example, visits 1 and 2 are not shown for leaf nodes. Visit 3 is also not shown for any node, but would occur just before the node's item is popped from the stack.
The StackNode class represents a binary tree node that is in the process of being traversed. It is defined as follows:
public class StackNode { public BinTreeNode binTreeNode; public int numTimesVisited; public StackNode(BinTreeNode binTreeNode) { this.binTreeNode = binTreeNode; this.numTimesVisited = 0; } }
The binTreeNode field records one of the nodes of the binary tree.
The numTimesVisited field records the number of times the node has been visited as part of general binary tree traversal.
The TreeIterator class implements the general binary tree traversal using a Stack<StackNode> object, and is the base class for the classes PreOrderIterator, PostOrderIterator, and InOrderIterator. It is completely implemented except for a single method called advance. The task of the advance method is to move to the next step in the general binary tree traversal. It should work as follows:
Moving down in the tree is accomplished by pushing a new StackNode onto the stack. Moving up the tree is accomplished by popping the top element from the stack.
Each of these iterator classes is defined as a sub-class of TreeIterator. They each require a single method to be implemented: isReadyToVisit. This method is passed a StackNode object, and depending on how many times it has been visited by the general traversal algorithm, should return whether or not the node is ready to visit by the pre-order, post-order, or in-order traversal.
Note that because isReadyToVisit is called before advance, the numTimesVisited field will contain 0 before the first time the node is visited, 1 before the second time the node is visited, etc.
To get started, download lab10.zip from the class web page and import it into your Eclipse workspace.
Your main task is to implement the advance method of TreeIterator and the isReadyToVisit method of PreOrderIterator, PostOrderIterator, and InOrderIterator. You can run the TreeDemo class to try the various traversal algorithms on randomly generated trees.
If you have time, try implementing the LevelOrderIterator class. The class is partly implemented; all you need to do is implement the next method. Hint: the approach is very similar to the iterative level-order traversal you implemented in Lab 9.
From a terminal window, run the commands:
cd cd eclipse-workspace submit102 lab10