Project 3: Treaps

Due: Tuesday, November 5, before 9:00 pm


Addenda


Objectives

The objectives of this programming assignment are:


Introduction

A treap is a combination of a binary search tree (BST) and a heap. You should be very familiar with BSTs at this point in the semester, but you probably haven't encountered heaps yet. For this project, you only need two concepts from heaps:

The following figure shows a treap in which the data are letters (or strings) and the priorities are integers.

Sample Treap with String Data and Integer Priorities
(Image source: http://cseweb.ucsd.edu/~kube/cls/100/Lectures/lec5/lec5-2.html#pgfId-955731)

A treap must be both a BST and have the max-heap property, which means insertions and deletions must check that the max-heap property holds and fix the tree if it does not. It will turn out that this is not as bad as it sounds. The max-heap property can always be repaired by applying single rotations.

Tree Rotations

Single tree rotations are local modification to a tree that can be used to repair violations of the max-heap property while maintaining the BST structure. The restructurings that can be achieved using single rotations are a subset of those possible with trinode restructuring. The figure below illustrates left and right single rotations.

Tree Rotations
Left and Right Single Rotations
(Image source: http://cseweb.ucsd.edu/~kube/cls/100/Lectures/lec5/lec5-5.html#pgfId-955859)

It is not difficult to see that rotations preserve the BST ordering: in both images, we have \(a < Y < b < X < c\), and we assume that the subtrees \(a\), \(b\), and \(c\) were constructed correctly before the rotation occured. How dow we use rotations to make local fixes to the max-heap property? Suppose that in the left picture, the priority of \(Y\) were higher than the priority of \(X\), violating the max-heap property; then a right rotation would make \(Y\) the parent of \(X\), correcting the error.

We can use single rotations, along with standard BST operations, to maintain a treap.

So why bother with treaps? One interesting fact is that if we build a treap using random priorities it will almost always be balanced (meaning, balanced with high probability); at the same time, treaps are easier to implement than balanced trees such as AVL or red-black trees. Also, there are other operations that can be performed efficiently on treaps, such as joining two treaps to create a single combined treap, or splitting a treap into two treaps.

A good reference for additional information is this lecture on treaps from UCSD.


Assignment

Your assignment is to implement the Treap class using single rotation method described in the Introduction to maintain the treap properties. You must use the provided treap.h and treap.cpp files. You may not modify the public function declarations or private data, but you may add private helper functions.

Although several test programs are provided, you are responsible for thoroughly testing your program. It is particularly important that your code run without segmentation faults, memory leaks, or memory errors. Memory leaks are considered as bad as segmentation fault since many segmentation faults are caused by poorly written destructors. A program with a poorly written destructor might avoid some segmentation faults but will leak memory horribly. Memory leaks will incur a penalty similar to that of a segmentation fault.

Following is a alist of member functions that must be implemented. Some of these functions are already implemented (or partially implemented) in treap.cpp; others will need to be written from scratch. Any helper functions that you write must be private and must be declared in treap.h.


Additional Requirements

Requirement: You must use the supplied treap.h and treap.cpp files. You may not modify any of the public method prototypes or private data, although you may add private functions.

Requirement: Your find(), insert() and remove() methods must all run in time proportional to the height of the treap.

Requirement: Your implementation must not permit duplicate data values. If an attempt is made to insert a duplicate value, insert() should leave the treap unchanged; it should not throw an exception or cause the program to crash.

Requirement: The treap properties must hold after any call to insert() or remove(). These commands must produce a valid treap.

Requirement: Your code must use single rotations as described in the Introduction to maintain the treap properties.

Requirement: Except for insert(), the provided function implementations should not be modified.


Provided Programs

The provided class files, treap.h and treap.cpp, comprise a partial implementation of a BST, providing a constructor, insert() function, and inorder() traversal, and it is possible to create and print a BST with no additional code. The following driver is provided:

Several sample test programs for the Treap class are provided below. However, it is your responsibility to write additional tests to ensure that your implementation is correct.


What to Submit

You must submit the following files to the proj3 directory.

If you followed the instructions in the Project Submission page to set up your directories, you can submit your code using this Unix command command.

cp treap.h treap.cpp ~/cs341proj/proj3/