3.3   Balanced Search Trees


This section under major construction.


We introduce in this section a type of binary search tree where costs are guaranteed to be logarithmic. Our trees have near-perfect balance, where the height is guaranteed to be no larger than 2 lg N.

2-3 search trees.

The primary step to get the flexibility that we need to guarantee balance in search trees is to allow the nodes in our trees to hold more than one key.

Definition.

A 2-3 search tree is a tree that either is empty or:

Anatomy of a 2-3 tree
A perfectly balanced 2-3 search tree (or 2-3 tree for short) is one whose null links are all the same distance from the root.

Proposition.

Search and insert operations in a 2-3 tree with N keys are guaranteed to visit at most lg N nodes.

Typical 2-3 tree built from random keys

However, we are only part of the way to an implementation. Although it would be possible to write code that performs transformations on distinct data types representing 2- and 3-nodes, most of the tasks that we have described are inconvenient to implement in this direct representation.

Red-black BSTs.

The insertion algorithm for 2-3 trees just described is not difficult to understand. We consider a simple representation known as a red-black BST that leads to a natural implementation.

Implementation.

Program RedBlackBST.java implements a left-leaning red-black BST. Program RedBlackLiteBST.java is a simpler version that only implement put, get, and contains.

Red-black BST construction

Deletion.

Proposition.

The height of a red-blackBST with N nodes is no more than 2 lg N.

Proposition.

In a red-black BST, the following operations take logarithmic time in the worst case: search, insertion, finding the minimum, finding the maximum, floor, ceiling, rank, select, delete the minimum, delete the maximum, delete, and range count.

Property.

The average length of a path from the root to a node in a red-black BST with N nodes is ~1.00 lg N.

Visualization.

The following visualization shows 255 keys inserted into a red-black BST in random order.


Exercises

  1. Which of the follow are legal balanced red-black BSTs?

    Legal balanced red-black BSTs

    Solution. (iii) and (iv) only. (i) is not balanced, (ii) is not in symmetric order or balanced.

  2. True or false: If you insert keys in increasing order into a red-black BST, the tree height is monotonically increasing.

    Solution. True, see the next question.

  3. Draw the red-black BST that results when you insert letters A through K in order into an initially empty red-black BST. Then, describe what happens in general when red-black BSTs are built by inserting keys in ascending order.

    Solution. The following visualization shows 255 keys inserted into a red-black BST in ascending order.


  4. Answer the previous two questions for the case when the keys are inserted in descending order.

    Solution. False. The following visualization shows 255 keys inserted into a red-black BST in descending order.

  5. Create a test client TestRedBlackBST.java.

Creative Problems

  1. Certification. Add to RedBlackBST.java a method is23() to check that no node is connected to two red links and that there are no right-leaning red links. Add a method isBalanced() to check that all paths from the root to a null link have the same number of black links. Combine these methods with isBST() to create a method isRedBlackBST() that checks that the tree is a BST and that it satisfies these two conditions.
  2. Fundamental theorem of rotations. Show that any BST can be transformed into any other BST on the same set of keys by a sequence of left and right rotations.

    Solution sketch: rotate the smallest key in the first BST to the root along the leftward spine; then recur with the resulting right subtree until you have a tree of height N (with every left link null). Do the same with the second BST. Remark: it is unknown whether there exists a polynomial-time algorithm for determining the minimum number of rotations needed to transform one BST into the other (even though the rotation distance is at most 2N - 6 for BSTs with at least 11 nodes).

  3. Delete the minimum. Implement the deleteMin() operation for RedBlackBST.java by maintaining the correspondence with the transformations given in the text for moving down the left spine of the tree while maintaining the invariant that the current node is not a 2-node.
  4. Delete the maximum. Implement the deleteMax() operation for RedBlackBST.java. Note that the transformations involved differ slightly from those in the previous exercise because red links are left-leaning.
  5. Delete. Implement the delete() operation for RedBlackBST.java, combining the methods of the previous two exercises with the delete() operation for BSTs.

Web Exercises

  1. Given a sorted sequence of keys, describe how to construct a red-black BST that contains them in linear time.
  2. Suppose that you do a search in a red-black BST that terminates unsuccessfully after following 20 links from the root. Fill in the blanks below with the best (integer) bounds that you can infer from this fact about any unsuccessful search
    • Must follow at least ______ links from the root
    • Need follow at most _______ links from the root
  3. With 1 bit per node we can represent 2-, 3-, and 4-nodes. How many bits would we need to represent 5-, 6-, 7-, and 8-nodes.
  4. Substring reversing. Given a string of length N, support the following operations: select(i) = get the ith character, and reverse(i, j) = reverse the substring from i to j.

    Solution sketch. Maintain the string in a balanced search tree, where each node records the subtree count and a reverse bit (that interchanges the role of the left and right children if there are an odd number of reverse bits on the path from the root to the node). To implement select(i), do a binary search starting at the root, using the subtree counts and reverse bits. To implement reverse(i, j), split the BST at select(i) and select(j) to form three BSTs, reverse the bit of the middle BST, and join them back together using a join operation. Maintain the subtree counts and reverse bits when rotating.

  5. Memory of a BST. What is the memory usage of a BST and RedBlackBST and TreeMap?

    Solution. MemoryOfBSTs.java.

  6. Randomized BST. Program RandomizedBST.java implements a randomized BST, including deletion. Expected O(log N) performance per operations. Expectation depends only on the randomness in the algorithm; it does not depend on the input distribution. Must store subtree count field in each node; generates O(log N) random numbers per insert.

    Proposition. Tree has same distribution as if the keys were inserted in random order.

  7. Join. Write a function that takes two randomized BSTs as input and returns a third randomized BST which contains the union of the elements in the two BSTs. Assume no duplicates.

  8. Splay BST. Program SplayBST.java implements a splay tree.

  9. Randomized queue. Implement a RandomizedQueue.java so that all operations take logarithmic time in the worst case.

  10. Red-black BST with many updates. When performing a put() with a key that is already in a red-black BST, our RedBlackBST.java performs many unnecessary calls to isRed() and size(). Optimize the code so that these calls are skipped in such situations.