// 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)). */