/***********************************************************************/
/* file base_bst.cc */
/* contains the implementation of class members of class */
/* base_bst. */
/***********************************************************************/
#include "base_bst.h"
/***********************************************************************/
/* implementation of class base_bst */
/***********************************************************************/
/***********************************************************************/
/* constructor */
/***********************************************************************/
template <class type>
base_bst<type>::base_bst(const base_bst<type>& tree):container<type>(tree)
{
if (tree.head)
{
head= new bst_item<type>(*tree.head);
}
else
{
head= NULL;
}
}
/***********************************************************************/
/* public operator= */
/* copies its arguments' data members on the data members of */
/* its owner. */
/***********************************************************************/
template <class type>
const base_bst<type>& base_bst<type>::operator=(const base_bst<type>& tree)
{
this->sz= tree.size();
if (head != NULL)
{
delete head;
}
if (tree.head)
{
head= new bst_item<type>(*tree.head);
}
else
{
head= NULL;
}
return *this;
}
/***********************************************************************/
/* protected member function del_item */
/* workhorse for del, deletes an item */
/***********************************************************************/
template <class type>
void base_bst<type>::del_item(bst_item<type> *parent, bst_item<type> *it)
{
assert(it != NULL);
if (it->left)
{
bst_item<type> *old_it= it;
bst_item<type> *next_it= it->left;
while(next_it->right)
{
old_it= next_it;
next_it= next_it->right;
}
it->data= next_it->data;
del_item(old_it, next_it);
}
else
{
if (it->right)
{
bst_item<type> *old_it= it;
bst_item<type> *next_it= it->right;
while(next_it->left)
{
old_it= next_it;
next_it= next_it->left;
}
it->data= next_it->data;
del_item(old_it, next_it);
}
else
{
if (parent)
{
if (it == parent->left)
{
parent->left= NULL;
}
else
{
parent->right= NULL;
}
}
if (it == head)
{
head= NULL;
}
delete it;
this->sz--;
}
}
}
/***********************************************************************/
/* protected member function internal search takes an argument of type */
/* which specifies what data to search for and an argument of int */
/* in which 0 for 'not found' and 1 for 'found' is return. The return */
/* value is either a pointer on the node where the data was found or if*/
/* it was not found a pointer on the node where the search ended. */
/***********************************************************************/
template <class type>
bst_item<type> *base_bst<type>::parent_search(const type& dat)
{
bst_item<type> *it= head;
bst_item<type> *parent= NULL;
while (it)
{
if (it->data == dat)
{
return parent;
}
else
{
parent= it;
if (dat < it->data)
{
it= it->left;
}
else
{
it= it->right;
}
}
}
return parent;
}
/***********************************************************************/
/* protected member function child */
/* takes a pointer to bst_item and an argument of type. It determines */
/* whether the bst_item denoted by argument 1 has a child with data */
/* identical to argument 2. If so it returns a pointer to the child */
/* otherwise NULL. */
/***********************************************************************/
template <class type>
bst_item<type> *base_bst<type>::child(bst_item<type> *parent, const type& dat)
{
assert(parent != NULL);
if ((parent->left) && (dat == parent->left->data))
{
return parent->left;
}
else
{
if ((parent->right) && (dat == parent->right->data))
{
return parent->right;
}
else
{
return NULL;
}
}
}
/***********************************************************************/
/* protected member function add_item */
/* takes two pointer to bst_item and inserts the item pointed to by */
/* argument 2 as a child of the item pointed to by argument 1. */
/* There is no check if there already is a child. */
/***********************************************************************/
template <class type>
void base_bst<type>::add_item(bst_item<type> *parent, bst_item<type> *it)
{
if (it)
{
this->sz++;
if (parent)
{
if (it->data < parent->data)
{
parent->left= it;
}
else
{
parent->right= it;
}
}
else
{
head= it;
}
}
}
/***********************************************************************/
/* constructor */
/***********************************************************************/
template <class type>
base_bst<type>::base_bst()
{
head= NULL;
}
/***********************************************************************/
/* destructor */
/***********************************************************************/
template <class type>
base_bst<type>::~base_bst()
{
if (head != NULL)
{
delete head;
}
}
/***********************************************************************/
/* public member function in */
/* returns 1 if the data passed as single argument is found int the */
/* base_bst, 0 otherwise. */
/***********************************************************************/
template <class type>
int base_bst<type>::in(const type& dat)
{
bst_item<type>* parent= parent_search(dat);
if (((parent == NULL) && (this->sz > 0))
|| ((parent) && (child(parent,dat))))
{
return 1;
}
else
{
return 0;
}
}
/***********************************************************************/
/* public member function del */
/* takes an argument of type and deletes the node in the base_bst */
/* containing identical data as the argument. It returns 1 if anything */
/* was deleted, 0 otherwise. */
/***********************************************************************/
template <class type>
int base_bst<type>::del(const type& dat)
{
if (head != NULL)
{
bst_item<type> *parent= parent_search(dat);
if (parent)
{
bst_item<type> *it= child(parent,dat);
if (it)
{
del_item(parent, it);
return 1;
}
}
else
{
del_item(parent, head);
return 1;
}
}
return 0;
}
/***********************************************************************/
/* public member function clear */
/* takes no arguments and empties the whole base_bst */
/***********************************************************************/
template <class type>
void base_bst<type>::clear()
{
this->sz= 0;
if (head != NULL)
{
delete head;
}
head= NULL;
}
/***********************************************************************/
/* public member function iterator() */
/* takes no argument and returns a freshly created iterator for the */
/* base_bst. The iterator must be deleted by the calling function. */
/* Otherwise it will continue as garbage indefinitely. */
/***********************************************************************/
template <class type>
bst_iterator<type> *base_bst<type>::iterator()
{
bst_iterator<type> *tmp= new bst_iterator<type>(this);
return tmp;
}