#include "BinarySearchTree.H" #include /** * Implements an unbalanced binary search tree. * Note that all "matching" is based on the < method. */ /** * Construct the tree. */ template BinarySearchTree::BinarySearchTree( const Comparable & notFound ) : ITEM_NOT_FOUND( notFound ), root( NULL ) { cout <<"**BinarySearchTree constructor **" << endl; } /** * Copy constructor. */ template BinarySearchTree:: BinarySearchTree( const BinarySearchTree & rhs ) : root( NULL ), ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND ) { *this = rhs; } /** * Destructor for the tree. */ template BinarySearchTree::~BinarySearchTree( ) { makeEmpty( ); } /** * Insert x into the tree; duplicates are ignored. */ template void BinarySearchTree::insert( const Comparable & x ) { cout <<"**BST insert(X) ** " << endl; insert( x, root ); } /** * Remove x from the tree. Nothing is done if x is not found. */ template void BinarySearchTree::remove( const Comparable & x ) { remove( x, root ); } /** * Find the smallest item in the tree. * Return smallest item or ITEM_NOT_FOUND if empty. */ template Comparable & BinarySearchTree::findMin( ) const { return const_cast(elementAt( findMin( root ) )); } /** * Find the largest item in the tree. * Return the largest item of ITEM_NOT_FOUND if empty. */ template Comparable & BinarySearchTree::findMax( ) const { return const_cast(elementAt( findMax( root ) )); } /** * Find item x in the tree. * Return the matching item or ITEM_NOT_FOUND if not found. */ template Comparable & BinarySearchTree:: find( const Comparable & x ) const { return const_cast(elementAt( find( x, root ) )); } /** * Make the tree logically empty. */ template void BinarySearchTree::makeEmpty( ) { makeEmpty( root ); } /** * Test if the tree is logically empty. * Return true if empty, false otherwise. */ template bool BinarySearchTree::isEmpty( ) const { return root == NULL; } /** * Print the tree contents in sorted order. */ template void BinarySearchTree::printTree( ) const { if( isEmpty( ) ) cout << "Empty tree" << endl; else printTree( root ); } /** * Deep copy. */ template const BinarySearchTree & BinarySearchTree:: operator=( const BinarySearchTree & rhs ) { if( this != &rhs ) { makeEmpty( ); root = clone( rhs.root ); } return *this; } /** * Internal method to get element field in node t. * Return the element field or ITEM_NOT_FOUND if t is NULL. */ template const Comparable & BinarySearchTree:: elementAt( BinaryNode *t ) const { if (t == NULL) return ITEM_NOT_FOUND; else return t->element; } /** * Internal method to insert into a subtree. * x is the item to insert. * t is the node that roots the tree. * Set the new root. */ template void BinarySearchTree:: insert( const Comparable & x, BinaryNode * & t ) const { if( t == NULL ){ cout <<"**BST insert(X, BN t) **" << endl; t = new BinaryNode( x, NULL, NULL ); } else if( x < t->element ) insert( x, t->left ); else if( t->element < x ) insert( x, t->right ); else ; // Duplicate; do nothing } /** * Internal method to remove from a subtree. * x is the item to remove. * t is the node that roots the tree. * Set the new root. */ template void BinarySearchTree:: remove( const Comparable & x, BinaryNode * & t ) const { if( t == NULL ) return; // Item not found; do nothing if( x < t->element ) remove( x, t->left ); else if( t->element < x ) remove( x, t->right ); else if( t->left != NULL && t->right != NULL ) // Two children { t->element = findMin( t->right )->element; remove( t->element, t->right ); } else { BinaryNode *oldNode = t; t = ( t->left != NULL ) ? t->left : t->right; delete oldNode; } } /** * Internal method to find the smallest item in a subtree t. * Return node containing the smallest item. */ template BinaryNode * BinarySearchTree::findMin( BinaryNode *t ) const { if( t == NULL ) return NULL; if( t->left == NULL ) return t; return findMin( t->left ); } /** * Internal method to find the largest item in a subtree t. * Return node containing the largest item. */ template BinaryNode * BinarySearchTree::findMax( BinaryNode *t ) const { if( t != NULL ) while( t->right != NULL ) t = t->right; return t; } /** * Internal method to find an item in a subtree. * x is item to search for. * t is the node that roots the tree. * Return node containing the matched item. */ template BinaryNode * BinarySearchTree:: find( const Comparable & x, BinaryNode *t ) const { if( t == NULL ) return NULL; else if( x < t->element ) return find( x, t->left ); else if( t->element < x ) return find( x, t->right ); else return t; // Match } /****** NONRECURSIVE VERSION************************* template BinaryNode * BinarySearchTree:: find( const Comparable & x, BinaryNode *t ) const { while( t != NULL ) if( x < t->element ) t = t->left; else if( t->element < x ) t = t->right; else return t; // Match return NULL; // No match } *****************************************************/ /** * Internal method to make subtree empty. */ template void BinarySearchTree:: makeEmpty( BinaryNode * & t ) const { if( t != NULL ) { makeEmpty( t->left ); makeEmpty( t->right ); delete t; } t = NULL; } /** * Internal method to print a subtree rooted at t in sorted order. */ template void BinarySearchTree::printTree( BinaryNode *t ) const { if( t != NULL ) { printTree( t->left ); cout << t->element << endl; printTree( t->right ); } } /** * Internal method to clone subtree. */ template BinaryNode * BinarySearchTree::clone( BinaryNode * t ) const { if( t == NULL ) return NULL; else return new BinaryNode( t->element, clone( t->left ), clone( t->right ) ); } template int BinarySearchTree:: size( ) { return size(this->root); } template int BinarySearchTree:: size( BinaryNode *t ) const { if( t == NULL ) return 0; else return 1 + size(t->left) + size(t->right); } template BinarySearchTreeItr:: BinarySearchTreeItr( BinarySearchTree *t ) { arraySize = t->size(); current = 0; array = new (Comparable *)[arraySize]; fillItr(t->root); current = 0; } template void BinarySearchTreeItr:: fillItr( BinaryNode *t ) { if (t != NULL) { array[current++] = &(t->element); fillItr(t->left); fillItr(t->right); } }