template <typename Comparable>
class BinarySearchTree
{
public:
BinarySearchTree()
:root(NULL)
{
}
BinarySearchTree(const BinarySearchTree &rhs)
{
if (this != &rhs)
{
MakeEmpty();
this = &rhs;
}
return *this;
}
~BinarySearchTree()
{
MakeEmpty();
}
const BinarySearchTree &operator= (const BinarySearchTree &rhs)
{
if ( this != &rhs )
{
MakeEmpty();
root = Clone(rhs.root);
}
return *this;
}
const Comparable &FindMin() const
{
return FindMin(root)->element;
};
const Comparable &FindMax() const
{
return FindMax(root)->element;
};
bool Contains(const Comparable &x) const
{
return Contains(x,root);
};
bool IsEmpty() const
{
return root == NULL;
}
void PrintTree( ostream & out = cout ) const
{
if ( IsEmpty() )
{
out << “Empty Tree”<< endl;
}
else
{
PrintTree(root, out);
}
}
void MakeEmpty()
{
MakeEmpty(root);
}
void Insert(const Comparable &x)
{
Insert(x, root);
};
void Remove(const Comparable &x)
{
Remove(x, root);
};
int Height(BinaryNode *t) const
{
if ( t == NULL )
{
return -1;
}
else
{
return 1 + Max(Height(t->left), Height(t->right));
}
}
int Max(int a, int b) const
{
return (a > b) ? (a) : (b);
}
private:
struct BinaryNode
{
Comparable element;
BinaryNode *left;
BinaryNode *right;
BinaryNode(const Comparable &theElement, BinaryNode *lt, BinaryNode *rt)
:element(theElement),left(lt),right(rt)
{
}
};
BinaryNode *root;
void Insert(const Comparable &x, BinaryNode* &t) const
{
if ( t == NULL )
{
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
{
// do nothing
}
}
void Remove(const Comparable &x, BinaryNode* &t) const
{
if (t == NULL)
{
return;
}
if ( x < t->element)
{
return Remove(x, t->left);
}
else if ( t->element < x)
{
return Remove(x, t->right);
}
else if ( t->left != NULL && t->right != NULL)
{
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;
}
}
BinaryNode *FindMin(BinaryNode *t) const
{
if (t == NULL)
{
return NULL;
}
if (t->left == NULL)
{
return t;
}
return FindMin(t->left);
};
BinaryNode *FindMax(BinaryNode *t) const
{
if (t != NULL)
{
while (t->right != NULL)
{
t = t->right;
}
}
return t;
};
bool Contains(const Comparable &x, BinaryNode *t) const
{
if (t == NULL)
{
return false;
}
else if(x < t->element)
{
return Contains(x, t->left);
}
else if (t->element < x)
{
return Contains(x, t->right);
}
else
{
return true;
}
}
void MakeEmpty(BinaryNode* &t)
{
if ( t != NULL )
{
MakeEmpty( t->left );
MakeEmpty( t->right );
delete t;
}
t = NULL;
}
void PrintTree(BinaryNode *t, ostream &out) const
{
if ( t != NULL)
{
PrintTree(t->left, out);
out<< t->element <<endl;
PrintTree(t->right, out);
}
}
BinaryNode *Clone(BinaryNode *t) const
{
if ( t == NULL)
{
return NULL;
}
return new BinaryNode(t->element, Clone(t->left), Clone(t->right));
}
};