Climbing Trees

Implemenenting an AVL Tree

Project Due: 11:59 PM Friday, July 26

1.0 Objective

There is nothing too clever or too complex about this project. You are simply required to implement a correct version of an AVL tree. You will learn how to insert, delete, and search for nodes in a properly balanced AVL tree. A basic skeleton of the code will be provided for you and you will simply fill in the blanks.

2.0 Project Description

2.1 Basic Program
The basic program is called Tester and all code for this main class has been provided for you. It simply prints a menu for the user to choose from and reads their request. The options are:

  1. Insert a node.
  2. Find a node.
  3. Delete a node.
  4. Print the tree.
  5. Quit

All of these should be pretty self explanatory. The only one that needs a little bit more discussion is the print tree function. Since it is difficult to print out any arbitrary sized tree in a manner that looks meaningful (in other words, that looks like a tree), this option only prints out the tree through the first 4 levels. If their are more levels than this in the tree, they simply will not get printed out - it doesn't mean they don't exist. The file test-1.dat (available in the provided code section), shows a sample session for the program and shows what the tree print outs look like.

What you will be required to do for this project is to implement the AVLTree class. A skeleton of this class has been provided for you in the AVLTree.java file. This file indicates all the methods you are expected to fill in. A breif discussion of each of these methods is provided for you in the next section. The TreeNode class for this project is already provided for you. This is what your AVLTree will use for nodes.

Since the idea of this project is to teach you how to build and maintain an AVL tree, the TreeNodes for this project do not contain a data reference; instead, they only contain a key reference. For this project, all keys will be of the Integer class type. This class is provided by the Java API so you do not have to implement it. In fact, you never need to deal with this class directly. Only the Tester program needs to create Integer objects (and since that's provided for you, you don't have to worry about it).

2.2 Implementing AVLTree.java
You will be required to implement at least ? different methods in the AVLTree class. You can create more if you like but you must implement the following methods:

Method Description
private Object search (Comparable key, TreeNode subRoot) This method searches the tree and tries to find the node with a key equal to the one passed into the method. If the node is not found, this method should return null. Otherwise, this method should return the key found in the root (remember, for this project, the data and key for a node are the same thing). For more information on how to implement the search() method, see the psuedo-code example provided in class.
private boolean insert (Comparable key, TreeNode subRoot, TreeNode prev) This class actually does the insertion work. It should not only insert a node into the tree, but should make sure the tree is still a valid AVL tree after the insert. To achieve this objective, this function may need to call the balanceTree() method. The boolean value returned is used to indicate if the subTree rooted at subRoot changed height. For more information on how to implement the insert() method, see the psuedo-code example provided in class.
private boolean delete(Comparable key, TreeNode subRoot, TreeNode prev, TreeNode data) This class actually does the deletion work. It should not only delete a node from the tree, but should make sure the tree is still a valid AVL tree after the delete. To achieve this objective, this function may need to call the balanceTree() method. The boolean value returned is used to indicate if the subTree rooted at subRoot changed height. The data parameter passed in is where the deleted data should be placed. This data will then be returned to the user. If the key is not found in the tree, this data variable should not be changed at all. For more information on how to implement the delete() method, see the psuedo-code example provided in class.
private void balanceTree (TreeNode subRoot, TreeNode prev) This node checks to see if the subRoot is right heavy (balFactor == 2) or left heavy (balFactor == -2). It then calls the appropriate rotate methods to re-balance the tree. For more information on how to implement the balanceTree() method, see the psuedo-code example provided in class.
private void rotateLeft (TreeNode subRoot, TreeNode prev) This node replaces subRoot with it's right child and makes the subRoot the left child of the child that replaced it. For more information on how to implement the rotateLeft() method, see the psuedo-code example provided in class.
private void rotateRight (TreeNode subRoot, TreeNode prev) This node replaces subRoot with it's left child and makes the subRoot the right child of the child that replaced it. For more information on how to implement the rotateRight() method, see the psuedo-code example provided in class.
private void rotateRightLeft (TreeNode subRoot, TreeNode prev) This method first calls rotateRight with subRoot's right child. It then calls rotateLeft on the subRoot itself. For more information on how to implement the rotateRightLeft() method, see the psuedo-code example provided in class.
private void rotateLeftRight (TreeNode subRoot, TreeNode prev) This method first calls rotateLeft with subRoot's left child. It then calls rotateRight on the subRoot itself. For more information on how to implement the rotateLeftRight() method, see the psuedo-code example provided in class.

Along with these methods, the following methods are already written and provided for you:

Method Description
public Object search(Comparable key) This method is simply the outward interface to the user. All it does is call private search() with the key and root. You should never need to use this method.
public void insert(Comparable key) This method is simply the outward interface to the user. If the tree is empty, this method simply inserts the first node in the tree. Otherwise, it calls the private insert() method with the key, root, and null (there is no previous node for the root). You should never need to use this method.
public Object delete(Comparable key) This method is simply the outward interface to the user. First, it creates a TreeNode object to store the deleted nodes data in. Then it calls the private delete() method with the key, root, null (there is no previous node for the root), and the data object. When the private delete returns, this method returns the key in the data object. If the node was not found, this key should still be null. You should never need to use this method.
public void printTree() This method simply prints out the first 4 levels of the tree. What is nice about this method is that it prints the levels out in such a way that you can see the parent child relationships in the tree. For each node, it shows the data and the balance factor for the node (this is put in parenthesis after the data). If there are more than four levels, the remaining levels just do not get printed. It does not mean they do not exist, they are just not getting printed.
private void printLevel (Vector nodes, int level) This method is only called by printTree() and it simply prints out all the nodes at a particular level.
private int minValue(int x, int y) You will want to call this method when recalculating the balance factor for a particular node. It returns the minimum value of x and y.
private int maxValue(int x, int y) You will want to call this method when recalculating the balance factor for a particular node. It returns the maximum value of x and y.

YOU SHOULD NOT CHANGE ANY OF THESE METHODS. These are to remain as they are. Modifying them will result in lost points on your project. Of all these methods provided for you, you should only need to use the minValue() and maxValue() methods for recalculating the balance factor for a node.

3.0 Provided Code

To download the following code, simply right click on the link and do a Save As on the link. If you have any problems downloading this code, please let me know right away.

4.0 Running Your Program

Once your program has been compiled, it can be run in the following manner:

prompt> java Tester

You will then be prompted with a menu and asked to enter in selections based on whether you want to search, insert, or delete nodes from the tree. There is also an option to print the tree (up to the first 4 levels) and quit.

5.0 Handing in Your Project

The directory for handing in your program can be found at:

/p/course/cs367-mattmcc/public/username/p3

You should submit all *.java files that you created that are needed to compile your program. You should not submit any *.class files or any of the files we provided for you.

Also, be sure to comment your code well so that it can be easily browsed to see what is going on. Code that is excessively difficult to read will be penalized.

6.0 Grading

The project is due at 11:59 PM on Friday, July 26. NO LATE ASSIGNMENTS WILL BE ACCEPTED! The project will be graded out of 100 points and be graded on the following criteria:

All grading will be done on the Novas. This does not mean you have to do your project on a Nova, but if you use some other machine, make sure it works on a Nova before handing it in.

We will grade your code by running it against a series of test files and checking the output of the program against a known, correct implementation. Any differences in your output versus that of the correct implementation will result in a point deduction. Currently, the only test file provided is test-1.dat. This file contains a listing of the input to the program and what the proper output should be.More tests may (or may not) be provided for you in the coming week. Without a doubt, much more in depth tests will be run than this initial one provided. This means you should right some of your own test files and check for any errors.

We will also examine parts of your code to make sure that you are implementing the data structures as required. If you are getting the correct results but not implementing the proper data strcucture, your score will suffer severely. You must implement the proper data structures.