// binary search trees.      // 9/95 -bds -compiled but not tested
// Reference CLR, chapter 13
typedef int keytype;
struct node {keytype key; node* left; node* parent; node* right;};
typedef struct node* tree;// used when emphasizing the node plus descendents.
typedef struct node* noder; // used when emphasizing just the node.
const NULL = 0;
typedef int boolean;

boolean is_bst(tree t)
// Is true if non-null t has the binary search tree property (bst).
// This is written not with intent for computational use, 
// but just to show the definition of bst. 
  {return 
    ( t->left == NULL || is_bst(t->left) ) 
    &&
    ( t->left == NULL || t->left->key <= t->key )
    &&
    ( t->right == NULL || is_bst(t->right) ) 
    &&
    (t->right == NULL  || t->right->key >= t->key );
  }

struct node* tree_search(tree r, keytype k)
// Return the node containing key k.  Return null if none found.
  {
  if (r == NULL || r->key == k) return r;
  if (r->key < k) return tree_search(r->right, k);
  else           return tree_search(r->left, k);
  }

noder tree_min(tree r)
// Assumes non-null bst tree r. Returns node with smallest key.
  {return (r->left == NULL) ? r : tree_min(r->left);}

noder tree_max(tree r)
// Assumes non-null bst tree r. Returns node with largest key.
  {return (r->right == NULL) ? r : tree_max(r->right);}

noder tree_successor(noder z)
// Assumes z is a node of a tree.
// Returns node with smallest key greater than z's key.
  {
  if (z->right != NULL) return tree_min(z->right);
  // i.e. down to right once, then down to left repeated until can't continue.
  else 
    {
    noder y = z;
    while (y->parent->right == y) 
      y = y->parent;
    return y->parent; // one step up right
    // i.e. up from right repeated until can't continue, then up from left. 
    }
  }

void tree_insert(tree* t, noder z)
// Assumes *t is a bst tree, *z is a node not currently in *t. 
// Result: *t is modified to include *z, while preserving bst property.
  {
  noder r = *t;
  if (r == NULL) *t = z; 
  else if (r->key < z->key)
    tree_insert(&(r->right), z);
  else // (r->key >= z->key) 
    tree_insert(&(r->left), z);
  }

void tree_delete(tree* t, noder z)
// Assumes *z is a node in a bst tree *t. 
// Result: *t is modified to eliminate node *z, while preserving bst property.
  {
  noder 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. 
    noder p = z->parent;
    if (p == NULL) // z is root 
      *t = z;
    else if (z == p->left) 
      p->left = x; 
    else 
      p->right = x;
    if (x != NULL) x->parent = p;
    }
  else // z has two children.
    {
    x = tree_successor(z);
    z->key = x->key; // copy node key (and data)
    tree_delete(t, x); // x is sure to have no left child. 
    }
  }

/*
These functions all operate in worst case O(h) time,
where h is the height of the tree.

Theorem (CLR Theorem 13.6 or problem 13-3): 
If an n node tree is built by random insertions and deletions the 
expected height is O(lg(n)).  
*/
