// File: bstree.C // // A binary search tree class #include #include #include #include "bstree.h" // ======================================================== // BSTreeNode member functions // Constructors template BSTreeNode::BSTreeNode() {} template BSTreeNode::BSTreeNode(const TYPE& t) : data(t) {} template BSTreeNode::BSTreeNode( const TYPE& t, const BSTree& lt, const BSTree& rt) : data(t), left(lt), right(rt) {} template BSTreeNode::~BSTreeNode() { #ifndef NDEBUG cout << "Destroying node with data = " << data << endl ; #endif } template void *BSTreeNode::operator new(size_t n) { void *ptr ; MemoryError e ; ptr = malloc(n) ; if (ptr == NULL) throw(e) ; return ptr ; } template void BSTreeNode::operator delete(void *ptr) { if (ptr == NULL) return ; free(ptr) ; } // ======================================================== // BSTree member functions // Constructor // template BSTree::BSTree() { root = NULL ; } // Destructor (Beware!) // template BSTree::~BSTree() { delete root ; } // Inorder Traversal of a BSTree // template void BSTree::inorder() { if (root == NULL) return ; cout << "(" ; root->left.inorder() ; cout << " " << root->data << " " ; root->right.inorder() ; cout << ")" ; } // Insert functions // template void BSTree::insert(const TYPE& t) { if (root == NULL) { root = new BSTreeNode(t) ; return ; } if (t <= root->data) { root->left.insert(t) ; } else { root->right.insert(t) ; } } // returns pointer to BSTree where the root has key value == x. // returns NULL, if no such node. // template BSTree *BSTree::find(const TYPE& t) { if (root == NULL) return NULL ; if (t == root->data) { return this ; } else if (t < root->data) { return root->left.find(t) ; } else { return root->right.find(t) ; } } // Removes the root node of host subtree. Can be used in conjunction // with Search. // template void BSTree::removeroot() { BSTreeNode *temp ; if (root == NULL) return ; // Otherwise, we have found x temp = deleteroot() ; // temp should be cleaned up assert(temp->left.root == NULL) ; assert(temp->right.root == NULL) ; delete temp ; } // returns pointer to BSTree where the root has min key value. // returns NULL if BSTree is empty. // template BSTree *BSTree::min() { if (root == NULL) return NULL ; if (root->left.root == NULL) { // found min return this ; } else { return root->left.min() ; } } // returns pointer to BSTree where the root has max key value. // returns NULL if BSTree is empty. // template BSTree *BSTree::max() { if (root == NULL) return NULL ; if (root->right.root == NULL) { // found max return this ; } else { return root->right.max() ; } } // Returns 1 if tree is empty, returns 1 otherwise // template bool BSTree::empty() { return root == NULL ? true : false ; } template void *BSTree::operator new(size_t n) { void *ptr ; MemoryError e ; ptr = malloc(n) ; if (ptr == NULL) throw(e) ; return ptr ; } template void BSTree::operator delete(void* ptr) { if (ptr == NULL) return ; free(ptr) ; } // Protected member functions // Removes BSTreeNode with smallest key and returns a pointer // to the node. Returned pointer must be freed after use. // template BSTreeNode *BSTree::deletemin() { BSTreeNode *answer ; if (root == NULL) return NULL ; if (root->left.root == NULL) { // found min answer = root ; root = root->right.root ; answer->right.root = NULL ; return answer ; } else { return root->left.deletemin() ; } } // Removes BSTreeNode at the root and returns a pointer to. // the root. Returned pointer must be freed after use. // template BSTreeNode *BSTree::deleteroot() { BSTreeNode *answer, *temp ; answer = root ; // Easy Case 1: tree is a single node if (root->left.root == NULL && root->right.root == NULL) { root = NULL ; return answer ; } // Easy Case 2: tree has no left child if (root->left.root == NULL) { root = root->right.root ; answer->right.root = NULL ; // fix up answer return answer ; } // Easy Case 3: tree has no right child if (root->right.root == NULL) { root = root->left.root ; answer->left.root = NULL ; // fix up answer return answer ; } // Hard Case: tree has both left and right childern temp = root->right.deletemin() ; // make temp new root temp->left = root->left ; temp->right = root->right ; root = temp ; // fix up answer answer->left.root = NULL ; answer->right.root = NULL ; return answer ; }