// From the software distribution accompanying the textbook // "A Practical Introduction to Data Structures and Algorithm Analysis, // Third Edition" by Clifford A. Shaffer, Prentice Hall, 2007. // Source code Copyright (C) 2006 by Clifford A. Shaffer. // This file includes all of the pieces of the BST implementation // Include the node implementation #include "binnode.ht" // Include the dictionary ADT #include "dictionary.h" // Binary Search Tree implementation for the Dictionary ADT template class BST : public Dictionary { private: BinNode* root; // Root of the BST int nodecount; // Number of nodes in the BST // Private "helper" functions void clearhelp(BinNode*); BinNode* inserthelp(BinNode*, const Elem&); BinNode* deletemin(BinNode*, BinNode*&); BinNode* removehelp(BinNode*, const Key&, BinNode*&); bool findhelp(BinNode*, const Key&, Elem&) const; void printhelp(BinNode*, int) const; public: BST() { root = NULL; nodecount = 0; } // Constructor ~BST() { clearhelp(root); } // Destructor void clear() { clearhelp(root); root = NULL; nodecount = 0; } bool insert(const Elem& it) { root = inserthelp(root, it); nodecount++; return true; } bool remove(const Key& K, Elem& it) { BinNode* t = NULL; root = removehelp(root, K, t); if (t == NULL) return false; // Nothing found it = t->val(); nodecount--; delete t; return true; } bool removeAny(Elem& it) { // Delete min value if (root == NULL) return false; // Empty tree BinNode* t; root = deletemin(root, t); it = t->val(); delete t; nodecount--; return true; } bool find(const Key& K, Elem& it) const { return findhelp(root, K, it); } int size() { return nodecount; } void print() const { if (root == NULL) cout << "The BST is empty.\n"; else printhelp(root, 0); } }; // Clean up BST by releasing space back free store template void BST:: clearhelp(BinNode* root) { if (root == NULL) return; clearhelp(root->left()); clearhelp(root->right()); delete root; } // Insert a node into the BST, returning the updated tree template BinNode* BST:: inserthelp(BinNode* root, const Elem& it) { if (root == NULL) // Empty tree: create node return (new BinNodePtr(it, NULL, NULL)); if (Comp::lt(getKey::key(it), getKey::key(root->val()))) root->setLeft(inserthelp(root->left(), it)); else root->setRight(inserthelp(root->right(), it)); return root; // Return tree with node inserted } // Delete the minimum value from the BST, returning the revised BST template BinNode* BST:: deletemin(BinNode* root, BinNode*& S) { if (root->left() == NULL) { // Found min S = root; return root->right(); } else { // Continue left root->setLeft(deletemin(root->left(), S)); return root; } } // Return in R the element (if any) with value K. // Return the updated subtree with R removed from the tree. template BinNode* BST:: removehelp(BinNode* root, const Key& K, BinNode*& R) { if (root == NULL) return NULL; // Val is not in tree else if (Comp::lt(K, getKey::key(root->val()))) root->setLeft(removehelp(root->left(), K, R)); else if (Comp::gt(K, getKey::key(root->val()))) root->setRight(removehelp(root->right(), K, R)); else { // Found: remove it BinNode* temp; R = root; if (root->left() == NULL) // Only a right child root = root->right(); // so point to right else if (root->right() == NULL) // Only a left child root = root->left(); // so point to left else { // Both children are non-empty root->setRight(deletemin(root->right(), temp)); Elem te = root->val(); root->setVal(temp->val()); temp->setVal(te); R = temp; } } return root; } // Find a node with the given key value template bool BST:: findhelp( BinNode* root, const Key& K, Elem& e) const { if (root == NULL) return false; // Empty tree else if (Comp::lt(K, getKey::key(root->val()))) return findhelp(root->left(), K, e); // Check left else if (Comp::gt(K, getKey::key(root->val()))) return findhelp(root->right(), K, e); // Check right else { e = root->val(); return true; } // Found it } // Print out a BST template void BST:: printhelp(BinNode* root, int level) const { if (root == NULL) return; // Empty tree printhelp(root->left(), level+1); // Do left subtree for (int i=0; ival() << "\n"; // Print node value printhelp(root->right(), level+1); // Do right subtree }