SKEDSOFT

Design Analysis Of Algorithm

Insertion: Insertion of a node into an n-node red-black tree can be accomplished in O(lg n) time. We use a slightly modified version of the TREE-INSERT procedure to insert node z into the tree T as if it were an ordinary binary search tree, and then we color z red. To guarantee that the red-black properties are pre- served, we then call an auxiliary procedure RB-INSERT-FIXUP to recolor nodes and perform rotations. The call RB-INSERT(T, z) inserts node z, whose key field is assumed to have already been filled in, into the red-black tree T.

	RB-INSERT(T, z)
 1  y  nil[T]
 2  x  root[T]
 3  while x  nil[T]
 4      do y  x
 5         if key[z] < key[x]
 6            then x  left[x]
 7            else x  right[x]
 8  p[z]  y
 9  if y = nil[T]
10     then root[T]  z
11     else if key[z] < key[y]
12             then left[y]  z
13             else right[y]  z
14  left[z]  nil[T]
15  right[z]  nil[T]
16  color[z]  RED
17  RB-INSERT-FIXUP(T, z)

There are four differences between the procedures TREE-INSERT and RB-INSERT. First, all instances of NIL in TREE-INSERT are replaced by nil[T]. Second, we set left[z] and right[z] to nil[T] in lines 14-15 of RB-INSERT, in order to maintain the proper tree structure. Third, we color z red in line 16. Fourth, because coloring z red may cause a violation of one of the red-black properties, we call RB-INSERT-FIXUP(T, z) in line 17 of RB-INSERT to restore the red-black properties.

	RB-INSERT-FIXUP(T, z)
 1 while color[p[z]] = RED
 2     do if p[z] = left[p[p[z]]]
 3           then y  right[p[p[z]]]
 4                if color[y] = RED
 5                   then color[p[z]]  BLACK                     Case 1
 6                        color[y]  BLACK                        Case 1
 7                        color[p[p[z]]]  RED                    Case 1
 8                        z  p[p[z]]                             Case 1
 9                   else if z = right[p[z]]
10                           then z  p[z]                        Case 2
11                                LEFT-ROTATE(T, z)               Case 2
12                           color[p[z]]  BLACK                  Case 3
13                           color[p[p[z]]]  RED                 Case 3
14                           RIGHT-ROTATE(T, p[p[z]])             Case 3
15           else (same as then clause
                         with "right" and "left" exchanged)
16 color[root[T]]  BLACK

To understand how RB-INSERT-FIXUP works, we shall break our examination of the code into three major steps. First, we shall determine what violations of the red-black properties are introduced in RB-INSERT when the node z is inserted and colored red. Second, we shall examine the overall goal of the while loop in lines 1-15. Finally, we shall explore each of the three cases into which the while loop is broken and see how they accomplish the goal. Figure 13.4 shows how RB-INSERT-FIXUP operates on a sample red-black tree.

Figure 13.4: The operation of RB-INSERT-FIXUP. (a) A node z after insertion. Since z and its parent p[z] are both red, a violation of property 4 occurs. Since z's uncle y is red, case 1 in the code can be applied. Nodes are recolored and the pointer z is moved up the tree, resulting in the tree shown in (b). Once again, z and its parent are both red, but z's uncle y is black. Since z is the right child of p[z], case 2 can be applied. A left rotation is performed, and the tree that results is shown in (c). Now z is the left child of its parent, and case 3 can be applied. A right rotation yields the tree in (d), which is a legal red-black tree.

Which of the red-black properties can be violated upon the call to RB-INSERT-FIXUP? Property 1 certainly continues to hold, as does property 3, since both children of the newly inserted red node are the sentinel nil[T]. Property 5, which says that the number of black nodes is the same on every path from a given node, is satisfied as well, because node z replaces the (black) sentinel, and node z is red with sentinel children. Thus, the only properties that might be violated are property 2, which requires the root to be black, and property 4, which says that a red node cannot have a red child. Both possible violations are due to z being colored red. Property 2 is violated if z is the root, and property 4 is violated if z's parent is red. Figure 13.4(a) shows a violation of property 4 after the node z has been inserted.

The while loop in lines 1-15 maintains the following three-part invariant:

At the start of each iteration of the loop,

  1. Node z is red.
  2. If p[z] is the root, then p[z] is black.
  3. If there is a violation of the red-black properties, there is at most one violation, and it is of either property 2 or property 4. If there is a violation of property 2, it occurs because z is the root and is red. If there is a violation of property 4, it occurs because both z and p[z] are red.