CSCI 151 - Prelab 5 Binary Trees

Due at the start of class on Monday, March 13

In this prelab, you will familiarize yourself with some of the design and implementation issues in the upcoming lab 5. Please write or type up your solutions, and hand in a paper copy before class on Monday. Remember, late prelabs receive zero credit.

Part 1 - Binary Trees

As you may recall from class, a binary tree is either:

  1. empty, or
  2. a root node of data with a left and right (sub)tree.

Therefore, you will have three classes:

  1. an abstract class BinaryTree<T> to represent any binary tree,
  2. a subclass EmptyTree<T> of BinaryTree<T> to represent any empty binary tree, and
  3. a subclass ConsTree<T> of BinaryTree<T> to represent any non-empty binary tree. ("ConsTree is short for "Constructed Tree".)
In this way, any binary tree you create will either be Empty or Cons. The EmptyTree class won't have any class variables, as it is an empty structure. The ConsTree class, on the other hand, needs the following three class variables:

    private T	      	  data;
    private BinaryTree<T> left;
    private BinaryTree<T> right;

There are many methods that we will add to the basic BinaryTree classes. For each of these you will do the following:

  1. add it as an abstract method to the BinaryTree class.
  2. implement the method in the EmptyTree class.
  3. implement the method in the ConsTree class.

For example, for the height method, you would:

  1. add the following to BinaryTree:
        public abstract int height( );
    
  2. add the following to EmptyTree:
        public int height( ) { return -1; }
    
  3. add the following to ConsTree:
        public int height( ) { 
    	 return 1 + Math.max(left.height(),right.height()); 
        }
    

  1. We want a nodeCount method with the following header:
        public int nodeCount( ) 
    that returns the number of nodes / vertices in the tree (including the root). For the EmptyTree class this just returns 0. Write the method body for the ConsTree class.






  2. We want a leafCount method with the following header:
        public int leafCount( ) 
    that returns the number of leaves in the tree. For the EmptyTree class this returns 0.Write the method body for this method for the ConsTree class. You can assume there is and IsLeaf( ) method that says wheter a BinaryTree is a leaf node.





  3. We want a mirrorImage method with the following header:
        public BinaryTree<T> mirrorImage() 
    that returns a new tree that looks like the mirror image of the current tree (that is, a tree "flipped" around a vertical line through the root node). Don't forget to also flip the sub-trees. For the EmptyTree class this just returns a new EmptyTree. Write the method body for the ConsTree class.


  4. For the following tree, list the nodes as you would encounter them in a post-order, in-order, and pre-order.



Probably the trickiest method you will write is a method that reads in a binary tree from a file, and returns a new BinaryTree according to the file's contents. It should have the following method signature:

    public BinaryTree<String> loadFromFile(String filename)

The files in question will list the nodes of the tree in postorder sequence, one node per line. Each line contains a string, which is the data value stored in the node, and two tag bits. The first tag bit indicates whether or not this node has a left child or not. (1=oui,0=non). The second tag bit indicates whether the node has a right child or not.

For example, the tree to the right is represented as

    32 0 0
    74 0 1
    29 0 0
    63 1 0
    18 0 0
    83 1 1
    34 1 1

The information in the file is sufficient to uniquely determine a binary tree. The tree can be constructed from the file using the following pseudocode:


create an empty stack of binary trees (i.e. Stack<BinaryTree<String>>)

while there is another line of input in the file {
    read a line (containing data and two tags)

    if right tag is 1, pop an element from the stack and call it right

    if left tag is 1, pop an element from the stack and call it left

    create a new binary tree with data as its root and
           left and right as its subtrees (if they exist)

    push the new tree onto your stack
}

when you exit the while loop, the stack should contain one element
this element is the the tree represented by the file data (so return it!)
If the stack is empty, the tree has no nodes, so you know what kind of tree it is.

NOTE: the input file is left then right, but the algorithm
uses the right value first, then the left. Not a typo.
  1. For the following input, run the algorithm above and draw the tree this input describes.
  2.     E 0 0
        F 0 0
        D 1 1
        B 1 0
        C 0 0
        A 1 1