Math 176 - Programming Assignment #1
Some Suggestions and Software Aids
There are two software items that may help you debug your solution to
homework #1.
- A program to help you check that you have declared your classes and methods properly.
This program is called CheckAvlSignature. Copy CheckAvlSignature.class,
CheckClassDefn.class and ThreadedAvlTreeReference.class and ThreadedAvlTreeReference$AvlIterator.class
from the ProgHomework1 directory, and place them in the same
directory as your own ThreadedAvlTree class. Run CheckAvlSignature,
with the command "java CheckAvlSignature". It will either tell
you that your implementation of ThreadedAvlTree has the right methods, or print out
diagnostics about what is missing or wrong.
The source code for these three programs is available
in the same directory as the class files, if you would like to examine the source code.
How it works: CheckAvlSignature
uses the java.lang.reflect classes to compare the methods of the ThreadedAvlTreeReference
and ThreadedAvlTree classes. It expects that every method of the
first class is exactly signature in the second class. It also checks which
classes are extended and implemented. Finally, it recursively checks inner classes
in the same way.
- A sample method that you may wish to modify for yourown use: CheckAvlProperties
is a method that recursively checks the nodes in an AVL tree to see if all the properties
of binary search trees and threaded AVL trees are properly satisfied. You
cannot use this program as-is, but will need to rewrite it for your own classes. The
program checks the binary search tree ordering properties, it checks the AVL height
properties and that threads point to nodes that are (or at least appear to be) correct.
It does not check for every possible problem, but will catch most problems.
When you look at the code, you will see that I
wrote my implementation with a sentinal. I had hoped this would simplify the
threaded AVL tree implementation, but in the end it did not help much at all. I
suggest you do not use a sentinal node.
Some implementation suggestions:
- Your node class and iterator class should be inner classes of your ThreadedAvlTree
class. There are several advantages of using inner classes. The first
advantage is that by making the inner classes private, you make it impossible for the
programmer using your routines to use any methods or objects that they should not have
access to This forces them to use the correct methods from the Collections API.
The second advantage is that objects from the inner class automatically have access
to all the fields and methods of the object that created them. (The first advantage
could be achieved through the use of package access, but the second advantage could not,
at least not without added more fields to objects of the inner classes.)
- To implement remove() for your iterator, it is OK to call the remove() method from the TreadedAvlTree
class instead of re-writing the remove() method.
- You can test your threaded AVL tree implementation by comparing what it does with a Java
object
TreeSet
(which implements a Red-Black tree).
- Check out the figures illustrating how to rebalance
after deletion.
- Your ThreadedAvlTree class should have a field for the root node (
private AvlNode
root;
) and a field for the size (private int numElements;
). It
is recommended, but optional, that you also have references to the inorder first and
inorder last elements of the tree.
- Your AvlNode class should have fields for the key (
private Comparable key
),
the children (private AvlNode leftChild, rightChild;
) and the height (private
int height;
)
- Your AvlIterator class should have fields for the next node and for the previous node.
You will need the previous node to implement remove(). Actually there are
several ways to implement the AvlIterator and you may not need both fields.