// red black trees          // 9/95 -bds --compiles but not tested
// Reference: CLR, chapter 14
typedef int keytype;
struct node {keytype key; node* left; node* parent; node* right; int color;};

const black = 1; const red = 0; const NULL = 0;
typedef struct node* tree;// used when emphasizing a node pointer references
			  // the node plus its descendents.
typedef int boolean;

/*
These functions all operate in worst case theta(h) time,
where h is the height of the tree.
But h is theta(lg(n)) for an n node red-black tree [CLR, Lemma 14.1],
so this is good performance. 
  
Terminology convention:  All actual nodes are "internal nodes" of the tree.
If a node pointer is NULL, it is considered to point to a "leaf" 
(an "external node").  In other words the number of leaves is the number of
left and right pointers in the tree which are NULL.

A binary tree is a red black tree (rbt) if 

1.(bst) It has the binary search tree property, namely for each internal
node *z, z->left is a leaf or has a key less than z->key and 
z->right is a leaf or has a key greater than z->key.

Each node of the tree has a color, black or red.  By convention
all leaves are black, the colors of the internal nodes are stored and
modifyable.  The coloring must satisfy the following rules.

2.(rbt-1) For each internal node, all paths from a leaf to the node
have the same number of black nodes.  It will be convenient to refer
to the black height of an edge.  This is the maximum number of black
nodes on any path from a leaf up to the given edge.

  (rbt-1a) For every internal node, the two edges to it's children 
have the same black height.

3.(rbt-2) No edge joins two red nodes. 
In other words, no red node has a red parent.
(Intuitively, this condition is that the red nodes are scattered.)

4.(rbt-3) The root is black.
(Intuitively, redness can be "pushed off the top".)

Theorem:  
A binary tree has property rbt-1 if and only if it has property rbt-1a.

Proof: it is clear that rbt-1 => rbt-1a.  Conversely, argue by
induction on the height of the parent end of an edge.  

Induction basis: if the height of z is one, then the two children are 
leaves, hence black. There are only the two paths to z and they each have
one black node, so rbt-1 holds for all z of height 2.

Induction step: assume rbt-1a for all nodes and rbt-1 for nodes of height
less than h.  Let z be a node of height h.  Suppose the edge to z->left has
black height b.  If z->left is black, some path up to z->left is of length
b-1, and by the induction hypothesis, all paths up to z->left must have
b-1 black nodes, hence all paths up to z from the left have height b.
Similarly if z->left is red, all paths up to z->left have b black nodes,
hence all paths up to z from the left have b black nodes.  By a similar
argument, all paths up to z from the rigth have b' black nodes, where b'
is the black height of the edge from z to z->right.  Now, by the rbt-1a 
property b = b' and we are done.  QED.
           

We will be using diagrams to show tree structure. Here is the notation.

        y        Lower case denotes red and upper case denotes black, so
      h/ \h      nodes y and z are red, node x is black.  Underscore "_b"
      X   z      indicates a node whose color is not known or is not 
        h/ \h+1  relevant, "o" denotes a leaf.  The "h" or "h+1" beside an 
       _b   o    edge denotes the black height of that edge. */

void rotate(node* p, node* c)
// Assumes p is a node of a tree with non-null child c.
// Modifies the tree so that p is child of c, 
// and the bst property is preserved. 
  {
  if (c == p->left)
    {
    p->left = c->right;
    c->right = p;
    }
  else 
    {
    p->right = c->left;
    c->left = p;
    }
  c->parent = p->parent;
  p->parent = c;
  }
/* What rotations do: (black parent, red child example)
        P                                      c
       / \        --> rotate(p, c) -->        / \ 
      c   gamma                          alpha   P
     / \          <-- rotate(c, p) <--          / \ 
alpha   beta                                beta   gamma
*/

void tree_insert(tree* t, node* x); // declaration, see def in bst.cc
void insert_fix_colors(node* x); // declaration, see def below.

void rbt_tree_insert(tree* t, node* x)
// Assumes *t is a tree, *x is not a node of *t.
// Modifies *t to include node *x, while preserving the rbt property.
  {
  tree_insert(t, x); // Now tree has bst property.
  x->color = red; 
/* Let p be the parent of x.  What we just did:
      _p             _p
     1/ \1   -->    1/ \1
     o  _w          x  _w
                  1/ \1
                  o   o
  So the tree now also has the rbt-1 property, but there is a problem
  with rbt-2 if the parent is red and a problem with rbt-3 if x is the root.
*/
  insert_fix_colors(x); // Now the tree also has rbt-2 and rbt-3.
  }

void insert_fix_colors(node* x) // definition
// Assumes *x is a red node of a tree which has bst and rbt-1 properties,
// has rbt-2 property except possibly at x and it's parent (which may 
// both be red), and has rbt-3 unless *x is root.
// Result: all properties restored - tree is a red black tree again.
  {
  node* a; node* g; // aunt, grandparent
  node* p = x->parent; 
  if (p == NULL) {x->color = black; return;} // x is root.
  if (p->color == black) return; // nothing needs doing.
  else // x and p are red -- fix that.  
    {
    g = p->parent; // Being red, *p is not root. Also *g is black.
    a = (g->left == p) ? g->right : g->left; //aunt
/* There will be three cases: 
1. Aunt is red, (x on side or in middle -- doesn't matter)
2. Aunt is black, x on side
3. Aunt is black, x in middle (toughest case)
     1.              2.               3.
           |h+1            |h+1             |h+1
           G               G                G 
         h/ \h           h/ \h             /1\
         p   a   or      p   A    or      p   A
       h/ \h           h/ \h             / \
       S   x           S   x            x   S
    */
    if (a->color == red) // CLR case 1, no rotation needed.
      {
      p->color = black; a->color = black; g->color = red;
      insert_fix_colors(g);
      /* What we just did:  (gg is the great grandparent of unknown color)

                  _gg             _gg
                   |h+1            |h+1
                   G               g
                 h/ \h         h+1/ \h+1
                 p   a   -->     P   A
               h/ \h           h/ \h
               S   x           S   x

         After that change, we fixed colors at g, because gg may be red also.  
      */
      }
    else 
      if (x == g->right->left || x == g->left->right) // CLR case 2.  
	rotate(p, x);
        /* What we just did: (x in middle)

                  G                  G
                   \h                 \h
                    p                  p  
                  h/ \h     rot      h/ \h
                 x    S     -->      A   x  
               h/ \h                   h/ \h
               Y   Z                   Y   Z
           So now x is on the side, flow into case 3, 
	*/
      rotate(g, p); // CLR case 3.  x on the side
      p->color = black; g->color = red;
      /* What we just did: (for x on left side, similar for mirror image)

                  |h+1               |h+1
                  G                  P  
                h/ \h     rot      h/ \h
               p    A     -->      x   g  
             h/ \h                   h/ \h
             x   S                   S   A
      */
    }
  }

node* tree_successor(node* z); // declaration, see def in bst.cc
void delete_fix_colors(node* p, node* w); // declaration, see def below

void rbt_delete(tree* t, node* z)
// Assumes z is a node of the rbt *t.
// Modifies *t to remove node *x, while preserving the rbt property.
// This is the bst code, with modifications to get the colors right.
  {
  node* x;
  if (z->left == NULL || z->right == NULL) // z has at most one child.
    {
    x = (z->left == NULL) ? z->right : z->left;  
    // x is the (possibly) non-null child. 
    node* p = z->parent;
    // Now remove z:
    if (p == NULL) // then z is the root.
      *t = x; 
    else if (z == p->left) p->left = x; else p->right = x;
    if (x != NULL) x->parent = p;

    // Now fix colors.  
//  if z->color is red, no problem - deletion doesn't change rbt-1 or rbt-2.
    if (z->color == black)
      if (x != NULL)
        x->color = black;
        /* x must have been red, because the leaf child implies the 
	   black height of z is 1.  We did:   
			      _p         _p
                               |2         |2
                               Z          X 
                             1/ \1  --> 1/ \1
                             x   o      o   o
                           1/ \1
                           o   o
        */
      else // z is black and both children of z were leaves.
	{
	node* w;
	w = (p->left == z) ? p->right : p->left; // w is z's sibling.

        /* We did:   _p            _p
                    2/ \2         1/ \2
                    Z   _w   -->  o   _w
                  1/ \1      
                  o   o
        so we now do:
	*/
	delete_fix_colors(p, w);
	}
    }
  else // z has two children.
    {
    x = tree_successor(z);
    z->key = x->key; // copy node key (and data)
    rbt_delete(t, x); // x is sure to have no left child. 
    }
  }

inline node* sibling(node* p, node* x)
  {return (p->left == x) ? p->right : p->left;}
inline node* niece(node*p, node* x) // sibling's far side child
  {return (p->left == x) ? p->right->right : p->left->left;}

void delete_fix_colors(node* p, node* w) // definition
// Assumes p is parent of w in a tree which is an rbt tree except that the
// black height balance may not be true at p.  Let x be the sibling of w.
// It is assumed that if If black height balance fails it is precisely 
// because bh(w,p) = bh(x, p) + 1.  Therefore, we'll call x the deficient node.
// Result: the rbt property is restored.
  {
  node* x = sibling(p, w);
  node* n = niece(p, x); // far side from x.   
  node* s = sibling(w, n); // near side to x. 
  if (x != NULL && x->color == red) {x->color = black; return;}
  if (w->color == red) 
  // case 1. Deficient node has red sibling w.
    {
    rotate(p, w); 
    w->color = black; p->color = red;
    /* We did
                P                   W              
            h-1/ \h               h/ \h          
              X   w               p   N           
                h/ \h    -->  h-1/ \h      
                S   N          X    S     
    */
    delete_fix_colors(p, s); // new sibling is black.
    }
  else if (n->color == black && s->color == black) 
    // case 2, both of w's children are black.
    {
    w->color = red; 
    /* We did
                  |h'                |h'-1
                 _p                 _p             
                h/ \h+1            h/ \h          
                X   W              X   w          
                  h/ \h    -->       h/ \h       
                  S   N              S   N      
    */
    node* g = p->parent;
    delete_fix_colors(g, sibling(g, p)); // work up.
    }
  else // at least one of s and n is red.
    {
    if (n->color == black) 
    // case 3, w's "far" child, n is black.
      {
      rotate(w, s); 
      w->color = red; s->color = black;
      /* We did
                   .p                 .p             
                 h/ \h+1            h/ \h+1           
                 X   W              X    S          
                   h/ \h    -->        h/ \h       
                   s   N               B   w     
                 h/ \h                   h/ \h  
                 B   C                   C   N

      now flow into case 4. */
      }
    // case 4, w's "far" child, n is red.
    rotate(p, w); 
    n->color = black;
    w->color = p->color;
    p->color = black;
    /* We did
                |h'                |h'
               _p                 _w             
              h/ \h+1          h+1/ \h+1          
              X   W              P   N          
                h/ \h    -->   h/ \h 
               _s   n          X   _s           */
    }
  }
