In this lab you will write code to create "random" binary trees, and implement several binary tree traversal algorithms.

**Note**: Because a binary tree is a recursive data structure, most binary
tree algorithms can be expressed best recursively. In this
lab, all of the code you will write will be recursive, with
the exception of the implementation of the **LevelOrder** class.

The **BinTreeNode** interface describes the methods which may
be performed on the nodes of a binary tree. These methods are:

**void setLeft(BinTreeNode left)**- set the given node as the right sub-tree**void setRight(BinTreeNode right)**- set the given node as the left sub-tree**BinTreeNode getLeft()**- get the left sub-tree**BinTreeNode getRight()**- get the right sub-tree

You will use these methods to create and traverse binary trees.

The **BinTreeNodeVisitor** interface defines several methods
which you should use when traversing the nodes of a binary tree:

**void start(BinTreeNode node)**- call this method when your traversal algorithm arrives at a node for the first time**void visit(BinTreeNode node)**- call this method to visit the given node**void finish(BinTreeNode node)**- call this method when your traversal is completely finished with the node

In general, a recursive traversal algorithm should call **start**
when encountering a node for the first time, near the entry to the
recursive visitation method. It should call **visit** to
"officially" visit the node. Finally, it should call **finish**
when it is completely done with the node, typically just before
returning from the recursive visitation method.

You will implement several classes used by the **TreeDemo** class,
which is a Java GUI application that animates several binary tree
traversal algorithms. You can run the **TreeDemo** program
at any time by right-clicking on "TreeDemo.java" in the Package Explorer
and choosing "Run As->Java Application".

Your first task is to write a method that creates "random" binary trees.
This is the **MakeRandomTree** class. The method

BinTreeNode create(int numLevels, BinTreeNodeFactory factory)

will create a (possibly-empty) random binary tree with the given number of levels.
You will see a statement computing a double value called **prob**. You should
use the provided random number generator to generate a random double value
between 0.0 and 1.0. If the randomly-generated number is less than
**prob**, then the method should return null (an empty tree). Otherwise,
it should create a new node, where the left and right sub-trees of the new node
are random subtrees whose maximum number of levels is **numLevels-1**.

To test your implementation of **MakeRandomTree**, run the **TreeDemo**
program and click the "Random" button. You should see a tree that
looks something like the following:

You second task is to implement several binary tree traversal algorithms. These algorithms will visit each node in the binary tree.

In each traversal,
you will need to use the methods of the **BinTreeNodeVisitor** object passed
to the traversal method to record the various stages of visitation (start,
visit, finish) at each node.

You will need to handle the base case where one of the sub-trees of a node is null.

To test one of your traversal algorithms, run **TreeDemo**, create
a random tree, select the algorithm name from the combo box, and
click "Start!".

The **PreOrder** class implements a Pre-Order traversal. A
Pre-Order traversal visits the node, recursively traverses the left sub-tree,
and then recursively traverses the right sub-tree.

The **PostOrder** class implements a Post-Order traversal. A
Post-Order traversal recursively traverses the left sub-tree,
recursively traverses the right sub-tree, then visits the node,.

The **InOrder** class implements an In-Order traversal. A
In-Order traversal recursively traverses the left sub-tree,
visits the node,
and then recursively traverses the right sub-tree.

The **LevelOrder** class implements a Level-Order traversal.
A Level-order traversal first visits the root, then each child of the root,
then each grand-child, etc.
Unlike the
other traversals, Level Order is not defined recursively. Instead,
you should use a queue to keep track of the next node to be visited.
The algorithm for level order visitation is as follows:

create a queue

enqueue the root node

while the queue is not empty {

dequeue a node

start, visit, and finish the node

enqueue each child of the node

}

You may use a **java.util.LinkedList** object as a queue.
Create the linked list as follows:

LinkedList queue = new LinkedList<BinTreeNode>();

The **isEmpty** method returns whether or not the queue is empty.
Use the **addLast** method to enqueue nodes and the **removeFirst**
method to dequeue a node.

Level-Order traversal is also known as "Breadth First" traversal. When you run the animation for this traversal, it should be clear why.

To get started, get the file lab8.zip from the class web page and import it into your Eclipse workspace. The classes you will modify are in the "lab8" project.

When you have implemented each algorithm, demonstrate them for me.

To submit: from a terminal window, run the commands

cd cd eclipse-workspace submit102 lab8