#include <iostream.h>
template <class KeyType>
class BST
{
public:
BST ( ); // creates a new, empty BST
~BST ( ); // deletes a BST
void Insert ( KeyType ); // inserts a new node with given value
void Remove ( KeyType ); // removes a node with given value
bool Has ( KeyType ) const; // searches for a node with given value
void PrintInOrder ( ) const; // prints the elements in sorted order
bool IsEmpty ( ) const; // whether the BST contains any elements
void Clear ( ); // removes all elements from the BST
KeyType Maximum ( ) const; // returns the "largest" value
KeyType Minimum ( ) const; // returns the "smallest" value
KeyType Successor ( KeyType ) const; // returns the next "largest" value
KeyType Predecessor ( KeyType ) const; // returns the next "smallest" value
private:
struct bstnode
{
KeyType key;
bstnode* left;
bstnode* right;
bstnode* parent;
};
bstnode* root;
void Delete ( bstnode* ); // for use by Clear ( )
void Print ( bstnode* ) const; // for use by PrintInOrder (
)
bstnode* TreeMinimum ( bstnode* ) const; // for use by
Minimum ( ), Remove ( )
bstnode* TreeMaximum ( bstnode* ) const; // for use by
Maximum ( ), Remove ( )
bstnode* TreePredecessor ( bstnode* ) const; // for use by
Predecessor ( )
bstnode* TreeSuccessor ( bstnode* ) const; // for use by
Successor ( )
bstnode* TreeFind ( KeyType ) const; // used by Remove ( ),
Successor ( ), Predecessor ( )
};
template <class KeyType>
BST <KeyType> :: BST ( )
{
root = 0; // set to null
}
template <class KeyType>
void BST <KeyType> :: Insert ( KeyType newkey )
{
// allocate and initialize memory for new node
bstnode* newnode = new bstnode;
newnode -> key = newkey;
newnode -> left = newnode -> right = 0; // new node will be a leaf
// search for appropriate insertion point
bstnode* insertpoint = root; // will eventually be node to insert at
bstnode* newparent = 0; // will eventually be parent of new node
while ( insertpoint != 0 ) // traverse tree
{
newparent = insertpoint;
if ( newkey < insertpoint->key )
insertpoint = insertpoint->left;
else
insertpoint = insertpoint->right;
}
if ( newparent == 0 ) // never did any traversal
{
root = newnode;
root->parent = 0;
}
else
{
newnode -> parent = newparent;
if ( newkey < newparent->key ) // link in as appropriate child of newparent
newparent->left = newnode;
else
newparent->right = newnode;
}
}
template <class KeyType>
bool BST <KeyType> :: Has(KeyType searchkey) const
{
return ( TreeFind(searchkey) != 0 );
}
template <class KeyType>
void BST <KeyType> :: PrintInOrder ( ) const
{
Print ( root );
}
template <class KeyType>
void BST <KeyType> :: Print ( bstnode* current ) const
{
if ( current == 0 )
return;
Print ( current -> left );
cout << current -> key << endl;
Print ( current -> right );
}
template <class KeyType>
bool BST <KeyType> :: IsEmpty ( ) const
{
return ( root == 0 );
}
template <class KeyType>
void BST <KeyType> :: Clear ( )
{
Delete ( root );
root = 0;
}
template <class KeyType>
void BST <KeyType> :: Delete ( bstnode* current )
{
if ( current == 0 )
return;
Delete ( current -> left );
Delete ( current -> right );
delete current;
}
template <class KeyType>
KeyType BST <KeyType> :: Maximum ( ) const
{
return ( TreeMaximum ( root ) ) -> key;
}
template <class KeyType>
KeyType BST <KeyType> :: Minimum ( ) const
{
return ( TreeMinimum ( root ) ) -> key;
}
template <class KeyType>
BST < KeyType > :: bstnode* BST <KeyType> :: TreeMaximum ( bstnode* current )
const
{
if ( current == 0 )
// throw some exception
bstnode* max = current;
while ( max -> right != 0 )
max = max -> right;
return max;
}
template <class KeyType>
BST < KeyType > :: bstnode* BST <KeyType> :: TreeMinimum ( bstnode* current )
const
{
if ( current == 0 )
// throw some exception
bstnode* min = current;
while ( min -> left != 0 )
min = min -> left;
return min;
}
template <class KeyType>
BST < KeyType > :: bstnode* BST <KeyType> :: TreeFind ( KeyType searchkey )
const
{
bstnode* current = root;
// just like Binary Search of ordered array
while ( current != 0 )
{
if ( current->key == searchkey )
return current;
if ( current->key <= searchkey )
current = current->right;
else
current = current->left;
}
return 0; // never found anything
}
template <class KeyType>
KeyType BST <KeyType> :: Successor ( KeyType value ) const
{
bstnode* answer = TreeFind ( value );
if ( answer == 0 )
// throw some exception; value not in BST
answer = TreeSucessor ( answer );
if (answer == 0)
// throw some exception; no successor exists
return ( answer -> key );
}
template <class KeyType>
BST < KeyType > :: bstnode* BST <KeyType> :: TreeSuccessor ( bstnode* node )
const
{
// if node has a right subtree, want smallest entry in that subtree
if ( node -> right != 0 )
return TreeMinimum ( node );
// otherwise, walk up tree until we find a node which is a left child
bstnode* successor = node -> parent;
while ( ( successor != 0 ) && ( node == successor->right ) )
{
node = successor;
successor = successor -> parent;
}
return successor;
}
template <class KeyType>
KeyType BST <KeyType> :: Predecessor ( KeyType value ) const
{
bstnode* answer = Find ( value );
if ( answer == 0 )
// throw some exception; value not in BST
answer = TreePredecessor ( answer );
if (answer == 0)
// throw some exception; no predecessor exists
return ( answer -> key );
}
template <class KeyType>
BST < KeyType > :: bstnode* BST <KeyType> :: TreePredecessor ( bstnode* node )
const
{
// if node has a left subtree, want largest entry in that subtree
if ( node -> left != 0 )
return TreeMaximum ( node );
// otherwise, walk up tree until we find a node which is a right child
bstnode* predecessor = node -> parent;
while ( ( predecessor != 0 ) && ( node == predecessor->left ) )
{
node = predecessor;
predecessor = predecessor -> parent;
}
return predecessor;
}
template <class KeyType>
void BST <KeyType> :: Remove ( KeyType oldkey ) const
{
bstnode* location = TreeFind ( oldkey );
if ( location == 0 )
// throw some exception; node to be removed is not in BST
// select a node to splice out of the BST
bstnode* splicenode;
if ( ( location->left == 0 ) || ( location->right == 0 ) )
splicenode = location;
else
splicenode = TreeSuccessor ( location );
// filler is splicenode's child, if any
bstnode* filler;
if ( splicenode->left != 0 )
filler = splicenode->left;
else
filler = splicenode->right;
// splice out node
if ( filler != 0 )
filler -> parent = splicenode -> parent;
// promote node to fill the hole left
if ( splicenode->parent == 0 )
root = filler;
else if ( splicenode == (splicenode->parent)->left )
(splicenode->parent)->left = filler;
else
(splicenode->parent)->right = filler;
// copy data from node splicenode into "deleted" node
if ( splicenode != location )
location->key = splicenode->key;
delete splicenode;
}
template <class KeyType>
BST < KeyType > :: ~BST ( )
{
Clear ( );
}