ICS 211 Homework 12

Trees and Tree Traversals

0. Goals and Overview

The goal of this assignment is to practice creating and using different kinds of trees and to continue practicing the use of recursion.

You are welcome to reuse any code from the course website and from the textbook in implementing your own solution, but be aware of any differences between what you are given and what you must implement.

1. Types of Trees

In this assignment, all of the trees store values of type String. For the trees that also store a key (only the binary search tree), the key is of type Integer. Although you know the types of values and keys, all your tree code must use type variables, and only your test code can use types String and Integer.

In your test code, values are selected at random, using RandomString with a length of 6. Likewise keys are selected at random by calling randomInt.nextInt(1000) with your own java.util.Random randomInt variable.

The simplest kinds of trees in this assignment are binary trees. In this assignment, these trees are optional -- only do them if you so desire, and they will not affect your grade in any way.

The next kinds of trees in this assignment are binary search trees, which store both a key and a value. These trees are required.

The third kind of trees in this assignment are ternary search trees. In a ternary tree, each node has one or two values, and has zero, one, two, or three children. Each node always has at least one value. If the node has at least one non-null subtree, then the node must have both values. Again, these trees are optional.

The final kind of trees in this assignment are complete binary trees. These trees are perfect binary trees (meaning they have as many nodes as possible) on all but the last level. On the last level, all the nodes are as far to the left as possible. Because of this, the values in the tree can be stored in breadth-first order in an array, and this is what you must implement. These trees are required.

2. Methods

You must implement the same operations for all of these different data structures. The operations are:

For each iterator, I suggest that the constructor of the iterator do a recursive depth-first traversal of the tree, saving the values in a list, and then return the list's iterator. For this, you are welcome to use a standard Java list, you don't need to implement the list yourself. If you want more of a challenge, you are welcome to instead adapt the code from the TreeIterator of the BinarySearchTree class, which uses a stack to do an incremental tree traversal that returns one element at a time.

3. Examples

3.1 Binary Tree

This example is a binary tree with 6 nodes, and the indented equivalent. In the indented equivalent, to show that ezsdzs only has a right (not a left) child, I have added a - to represent the null subtree. This is optional for you.

              rahjmy

      uwwkrx              ezsdzs

nfmqge    ebeoap              pmqcxj

rahjmy
  uwwkrx
    nfmqge
    ebeoap
  ezsdzs
    -
    pmqcxj

3.2 Binary Search Tree

Adding in order the following values into a binary search tree should give the following tree:
                    864:rahjmy

          834:uwwkrx              956:ebeoap

      175:nfmqge                       962:ezsdzs

154:pmqcxj



864:rahjmy
  834:uwwkrx
    175:nfmqge
      154:pmqcxj
      -
    -
  956:ebeoap
    -
    962:ezsdzs

3.3 Ternary Search Tree

In this example we use a * to indicate that the second value in a node is not used, and group all the values in a node in (). Since there is no key, the sorting order is based on the string itself. The indent puts both values in a node onto the same line, followed by their subtrees if any. This example uses the notation that a node with 1 or 2 subrees uses - to mark the null subtrees.

              (rahjmy       uwwkrx)

   (ebeoap   nfmqge)     -             -

-       (ezsdzs *)   (pmqcxj *)

rahjmy  uwwkrx
  ebeoap  nfmqge
    -
    ezsdzs *
    pmqcxj *
  -
  -

3.4 Complete Binary Tree

Here values are just added in the order given.

                   rahjmy

       uwwkrx                   nfmqge

ebeoap         ezsdzs       pmqcxj

rahjmy
  uwwkrx
    ebeoap
    ezsdzs
  nfmqge
    pmqcxj
    -

4. Test code

Each of your four tree classes must have a main method with a unit test that creates a random tree of size at least 10, then performs at least two calls each to get, add, and remove, each time using the iterator (and also the keyIterator for the binary search tree) to verify that the correct values are in the tree in the correct order (except the unsorted binary tree has no correct order). Each of your unit tests must also make at least one call each to toString and indented, printing out the results.

5. Turning in the Assignment

Zip and turn in all your source files as h12.zip.

Use Laulima to turn in your zip file to the TA. Once you log into Laulima and select the ICS 211 site, on the left-hand side will be an assignments tab.