Project 4: Ordered Sets

Educational Objectives: On successful completion of this assignment, the student should be able to

Background Knowledge Required: Be sure that you have mastered the material in these chapters before beginning the project:
Binary Trees and Iterators, Binary Tree Construction, Associative Binary Trees, Generic Associative Containers, Set and Map Abstractions,

Operational Objectives: Implement a generic container class TRBT<T,P> based on the red-black tree algorithms for insertion and removal of elements and satisfying the conditions detailed in this document.

Deliverables: One file:

trbt.h      # contains the red-black tree definitions and implementations

Red-Black Trees

A red-black tree is a binary search tree whose nodes have a color attribute and which satisfies the following additional properties:

  1. Every node color is either red or black
  2. The root is black
  3. If a node is red, then all its children are black
  4. For each node N, all descending paths from N to a leaf have the same number of black nodes

Because a red-black tree (RBT) is a binary search tree (BST), there is a well defined binary search algorithm in an RBT that follows descending paths. An important feature of RBTs is that they have height bounded above by 2 log2 (n + 1), where n is the number of nodes in the RBT, so an RBT must be fairly "bushy". (In stark contrast, a BST can be severely "leggy", with height n - 1. We can define "bushy" and "leggy" asymptotically as having height O(log n) and Ω(n), respectively.) It follows that

Theorem 1. BST search in an RBT has worst case run time is O(log n), where n is the number of nodes.

The challenge is to make sure that the RBT properties are maintained as we insert and remove elements. It turns out that the RBT properties do not necessarily hold after an ordinary BST insert or remove operation, but that there are "repair" algorithms that bring the resulting BST back into compliance with the RBT rules. These algorithms restructure the BST by pruning and re-hanging subtrees and are called rotations.

Rotations are constant time algorithms, and they are combined into repair algorithms that iterate along a descending path in the RBT. It follows that BST insert or remove, followed by RBT repair, has run time O(log n). Consequently

Theorem 2. RBT insert and remove have worst case run time O(log n).

Detailed specifications of the algorithms, including proof of correctness of the asserted outcomes, are found in the text [Cormen, Ch 13].

Procedural Requirements

  1. Define and implement the classes TRBT<T,P> and TRBTIterator<T,P> in the file rbt.h. Also place all supporting definitions and implementations, such as operator overloads, in this file.

  2. Test your classes using the distributed test harness fcset.cpp.

  3. Write a brief description of your development and test methods and results and place this in the file header documentation of rbt.h.

  4. Submit the project using the script LIB/submitscripts/proj4submit.sh.

Code Requirements and Specifications

  1. T is the element type stored in the container.

  2. P is the predicate type used to determine order in the container.

  3. TRBT<T,P> should implement unimodal associative container semantics.

  4. TRBTIterator<T,P> should implement const bidirectional iterator semantics.

  5. TRBT<T,P> and TRBTIterator<T,P> should be in the fsu namespace.

  6. TRBT<T,P> should use composition with TBinaryTree<T>, as illustrated in TBST<T,P> (distributed in the file LIB/tcpp/tbst.h).

  7. TRBTIterator<T,P> should use composition with TBinaryTreeIterator<T>, as illustrated in TBSTIterator<T,P> (distributed in the file LIB/tcpp/tbst.h).

  8. Create TRBT<T,P> as a derived class of TBST<T,P>. In this plan, a good bit of code can be re-used (by inheritance), including complete re-use of BSTIterator using a typedef statement. However there may be a small runtime penalty in some of the operations, not enough to affect the asymptotic runtime. The file tbst.h will be in the library to facilitate this plan.

    A big advantage of this plan is that there is a predefined testing method already implemented as part of TBST:

    void TestRBT () const;
    

    You may observe that following this requirement will automatically ensure that several of the earlier requirements are satisfied.

  9. TRBT<T,P> should function correctly with the following definition of SetType:

    typedef fsu::CSet < T , fsu::TRBT < T , P > , P > SetType;
    

    That is, objects of type SetType should exhibit correct behavior for a unimodal ordered set of elements of type T and order predicate P as defined in the file cset.h and tested using fcset.cpp.

Hints