lab_avl

Awful AVL Trees

Assignment Description

In this lab we’ll practice AVL tree rotations and insertions, and see some silly test cases.

Lab Insight

AVL trees can be used to build data structures like sorted maps and sets. To be quite honest, Red-Black trees, another kind of self-balancing search tree, are used more often in these applications because inserting things into them is faster. However, the general search performance of AVL trees is better, and even though AVL trees sound complicated to implement, all they need is a careful implementation of rotations to work well. Either way, the general principle of using self-balancing trees for data is useful because it helps search for things in faster than the O(n) time we would need if all we had were linked lists. Without rolling the dice and hoping for the best (an actually workable strategy, as we will see in later data structures), balanced trees are the go-to for good worst case search performance. They are the basis for many other data structures (like the maps and sets we mentioned before) and algorithms (they’re better than naive lists if we’re going to be searching for things), and a useful data structure to have in our toolkits for a lot of problems.

Checking Out The Code

From your CS 225 git directory, run the following on EWS:

git fetch release
git merge release/lab_avl -m "Merging initial lab_avl files"

If you’re on your own machine, you may need to run:

git fetch release
git merge --allow-unrelated-histories release/lab_avl -m "Merging initial lab_avl files"

Upon a successful merge, your lab_avl files are now in your lab_avl directory.

As usual, don’t forget to take a look at Doxygen for lab_avl.

Implement Rotation Functions

You must implement rotateLeft(), rotateRight(), and rotateRightLeft(). We have implemented rotateLeftRight() for you as an example for implementing rotateRightLeft().

Implement the rebalance() Function

You must implement rebalance() function. rebalance() should, given a subtree, rotate the subtree so that it is balanced. You should assume that the subtree’s left and right children are both already balanced trees. The node’s height should always be updated, even if no rotations are required.

Implement the insert() Function

You must implement the insert() function. insert() should add a node with a key and value at the correct location in the tree, then rebalance appropriately (while returning from each recursive function) to fix the tree’s balance.

Implement the remove() Function

You must implement the remove() function. remove() should remove the node with the specified key from the tree, then rebalance appropriately (while returning from each recursive function) to fix the tree’s balance. You can assume that the key exists in the tree. You may want to use the swap() method.

Testing Your Code

To test your code, compile using make:

make

Then run it with:

./testavl color

You will see that the output is colored — green means correct output, red means incorrect output, and underlined red means expected output that was not present. This mode is a bit experimental, and it might cause problems with your own debugging output (or other problems in general). To turn it off, simply leave off the “color” argument:

./testavl

You may also diff your solution with our expected output:

./testavl | diff -u - soln_testavl.out

Type [Escape] [:] [q] [a] [ENTER] to exit vimdiff.

To make the catch test suite, run:

make test

After compiling the test suite, run the tests using:

./test

Submitting Your Work

The following files are used in grading:

  • avltree.cpp
  • avltree.h

All other files including any testing files you have added will not be used for grading.