#include "AvlTree.h" #include /** * Implements an unbalanced Avl search tree. * Note that all "matching" is based on the compares method. * @author Mark Allen Weiss */ /** * Construct the tree. */ template AvlTree::AvlTree( const Comparable & notFound ) : ITEM_NOT_FOUND( notFound ), root( NULL ) { } /** * Copy constructor. */ template AvlTree::AvlTree( const AvlTree & rhs ) : ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND ), root( NULL ) { *this = rhs; } /** * Destructor for the tree. */ template AvlTree::~AvlTree( ) { makeEmpty( ); } /** * Insert x into the tree; duplicates are ignored. */ template void AvlTree::insert( const Comparable & x ) { insert( x, root ); } /** * Remove x from the tree. Nothing is done if x is not found. */ template void AvlTree::remove( const Comparable & x ) { cout << "Sorry, remove unimplemented; " << x << " still present" << endl; } /** * Find the smallest item in the tree. * Return smallest item or ITEM_NOT_FOUND if empty. */ template const Comparable & AvlTree::findMin( ) const { return elementAt( findMin( root ) ); } /** * Find the largest item in the tree. * Return the largest item of ITEM_NOT_FOUND if empty. */ template const Comparable & AvlTree::findMax( ) const { return elementAt( findMax( root ) ); } /** * Find item x in the tree. * Return the matching item or ITEM_NOT_FOUND if not found. */ template const Comparable & AvlTree:: find( const Comparable & x ) const { return elementAt( find( x, root ) ); } /** * Make the tree logically empty. */ template void AvlTree::makeEmpty( ) { makeEmpty( root ); } /** * Test if the tree is logically empty. * Return true if empty, false otherwise. */ template bool AvlTree::isEmpty( ) const { return root == NULL; } /** * Print the tree contents in sorted order. */ template void AvlTree::printTree( ) const { if( isEmpty( ) ) cout << "Empty tree" << endl; else printTree( root ); } /** * Deep copy. */ template const AvlTree & AvlTree:: operator=( const AvlTree & 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 & AvlTree::elementAt( AvlNode *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. */ template void AvlTree::insert( const Comparable & x, AvlNode * & t ) const { if( t == NULL ) t = new AvlNode( x, NULL, NULL ); else if( x < t->element ) { insert( x, t->left ); if( height( t->left ) - height( t->right ) == 2 ) if( x < t->left->element ) rotateWithLeftChild( t ); else doubleWithLeftChild( t ); } else if( t->element < x ) { insert( x, t->right ); if( height( t->right ) - height( t->left ) == 2 ) if( t->right->element < x ) rotateWithRightChild( t ); else doubleWithRightChild( t ); } else ; // Duplicate; do nothing t->height = max( height( t->left ), height( t->right ) ) + 1; } /** * Internal method to find the smallest item in a subtree t. * Return node containing the smallest item. */ template AvlNode * AvlTree::findMin( AvlNode *t ) const { if( t == NULL) return t; while( t->left != NULL ) t = t->left; return t; } /** * Internal method to find the largest item in a subtree t. * Return node containing the largest item. */ template AvlNode * AvlTree::findMax( AvlNode *t ) const { if( t == NULL ) return t; 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 AvlNode * AvlTree::find( const Comparable & x, AvlNode *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 AvlTree::makeEmpty( AvlNode * & t ) const { if( t != NULL ) { makeEmpty( t->left ); makeEmpty( t->right ); delete t; } t = NULL; } /** * Internal method to clone subtree. */ template AvlNode * AvlTree::clone( AvlNode * t ) const { if( t == NULL ) return NULL; else return new AvlNode( t->element, clone( t->left ), clone( t->right ), t->height ); } /** * Return the height of node t or -1 if NULL. */ template int AvlTree::height( AvlNode *t ) const { return t == NULL ? -1 : t->height; } /** * Return maximum of lhs and rhs. */ template int AvlTree::max( int lhs, int rhs ) const { return lhs > rhs ? lhs : rhs; } /** * Rotate binary tree node with left child. * For AVL trees, this is a single rotation for case 1. * Update heights, then set new root. */ template void AvlTree::rotateWithLeftChild( AvlNode * & k2 ) const { AvlNode *k1 = k2->left; k2->left = k1->right; k1->right = k2; k2->height = max( height( k2->left ), height( k2->right ) ) + 1; k1->height = max( height( k1->left ), k2->height ) + 1; k2 = k1; } /** * Rotate binary tree node with right child. * For AVL trees, this is a single rotation for case 4. * Update heights, then set new root. */ template void AvlTree::rotateWithRightChild( AvlNode * & k1 ) const { AvlNode *k2 = k1->right; k1->right = k2->left; k2->left = k1; k1->height = max( height( k1->left ), height( k1->right ) ) + 1; k2->height = max( height( k2->right ), k1->height ) + 1; k1 = k2; } /** * Double rotate binary tree node: first left child. * with its right child; then node k3 with new left child. * For AVL trees, this is a double rotation for case 2. * Update heights, then set new root. */ template void AvlTree::doubleWithLeftChild( AvlNode * & k3 ) const { rotateWithRightChild( k3->left ); rotateWithLeftChild( k3 ); } /** * Double rotate binary tree node: first right child. * with its left child; then node k1 with new right child. * For AVL trees, this is a double rotation for case 3. * Update heights, then set new root. */ template void AvlTree::doubleWithRightChild( AvlNode * & k1 ) const { rotateWithLeftChild( k1->right ); rotateWithRightChild( k1 ); } /** * Internal method to print a subtree in sorted order. * t points to the node that roots the tree. */ template void AvlTree::printTree( AvlNode *t ) const { if( t != NULL ) { printTree( t->left ); cout << t->element << endl; printTree( t->right ); } }