Please send questions to
st10@humboldt.edu .
/************************************************************/
/* implementation of .h file from *
/* http://www.cs.colorado.edu/~main/chapter10/bt_class.h */
/* */
/* Main and Savitch, "Data Structures and Other Objects */
/* using C++", 2nd edition, Addison-Wesley, Ch.10 */
/************************************************************/
//-----------------------------------------------------------
// File: binary_tree.template
// Name: Sharon Tuttle
// (implementing a .h file adapted from
// Savitch and Main)
// last modified: 3-31-05
//
// Template Class: binary_tree<Item> (a binary tree where each
// node contains an Item)
// See binary_tree.h for documentation.
//
// Because this is a template class, it is included in
// the header file, and not compiled separately.
//
// INVARIANT for the binary_tree class:
// 1. The items in the binary tree are stored in a linked
// structure, within nodes that have links to their left
// and right children. The root node is pointed to by
// the pointer root_ptr.
// 2. Each non-empty binary_tree instance always has a
// "current_node" --- the pointer current_ptr points to
// this node.
//--------------------------------------------------------------
#include <cassert> // Provides assert
#include "binary_tree_node.h" // Node template class
using namespace std;
/********************************************************/
/* CONSTRUCTORS and DESTRUCTOR */
/********************************************************/
// constructor
//
template <typename Item>
binary_tree<Item>::binary_tree( )
{
root_ptr = NULL;
current_ptr = NULL;
}
// copy constructor
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
binary_tree<Item>::binary_tree(const binary_tree<Item>& source)
{
root_ptr = tree_copy(source.root_ptr);
// where should current_ptr for new copy point?
// If copied an empty tree, current_ptr is NULL;
// otherwise, we'll start it at the root, I think.
if (root_ptr == NULL)
{
current_ptr = NULL;
}
else
{
current_ptr = root_ptr;
}
}
// destructor
//
// Library facilities used: binary_tree_node.h
template <typename Item>
binary_tree<Item>::~binary_tree()
{
tree_clear(root_ptr);
}
/*************************************************************/
/* ACCESSORS and other constant member functions (observers) */
/*************************************************************/
// postcondition: returns the number of nodes in the
// binary_tree.
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
size_t binary_tree<Item>::get_size( ) const
{
return tree_size(root_ptr);
}
// postcondition: returns true if the binary_tree is
// empty, returns false otherwise.
//
template <typename Item>
bool binary_tree<Item>::is_empty( ) const
{
return (root_ptr == NULL);
}
// retrieve
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
Item binary_tree<Item>::retrieve( ) const
{
assert(get_size( ) > 0);
return current_ptr->get_data( );
}
// is_root
//
template <typename Item>
bool binary_tree<Item>::is_root( ) const
{
return( (get_size( ) > 0) && (current_ptr == root_ptr) );
}
// is_leaf
//
template <typename Item>
bool binary_tree<Item>::is_leaf( ) const
{
return( (get_size( ) > 0) &&
(! has_left_child( ) ) &&
(! has_right_child( ) ) );
}
// has_parent
//
template <typename Item>
bool binary_tree<Item>::has_parent( ) const
{
return ( (get_size( ) > 0) &&
// if current isn't root, it must have a parent!
(current_ptr != root_ptr) );
}
// has_left_child
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
bool binary_tree<Item>::has_left_child( ) const
{
return ( (get_size( ) > 0) &&
(current_ptr->get_left( ) != NULL ) );
}
// has_right_child
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
bool binary_tree<Item>::has_right_child( ) const
{
return ( (get_size( ) > 0) &&
(current_ptr->get_right( ) != NULL ) );
}
/****************************************************/
/* MODIFIERS and other modifying member functions */
/****************************************************/
// create_root
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::create_root(const Item& entry)
{
assert( get_size( ) == 0 );
root_ptr = new binary_tree_node<Item>(entry);
current_ptr = root_ptr;
}
// add_left
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::add_left(const Item& entry)
{
assert( get_size( ) > 0 );
assert( has_left_child( ) == false );
binary_tree_node<Item> *new_left_ptr;
new_left_ptr = new binary_tree_node<Item>(entry);
current_ptr->set_left(new_left_ptr);
}
// add_right
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::add_right(const Item& entry)
{
assert( get_size( ) > 0 );
assert( has_right_child( ) == false );
binary_tree_node<Item> *new_right_ptr;
new_right_ptr = new binary_tree_node<Item>(entry);
current_ptr->set_right(new_right_ptr);
}
// add_left_subtree
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::add_left_subtree(binary_tree<Item>& left_subtree)
{
assert( get_size( ) > 0 );
assert( has_left_child( ) == false );
current_ptr->set_left(left_subtree.root_ptr);
}
// add_right_subtree
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::add_right_subtree(
binary_tree<Item>& right_subtree)
{
assert( get_size( ) > 0 );
assert( has_right_child( ) == false );
current_ptr->set_right(right_subtree.root_ptr);
}
// change
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::change(const Item& entry)
{
assert( get_size( ) > 0 );
current_ptr->set_data(entry);
}
// remove_left_subtree
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::remove_left_subtree( )
{
assert( get_size( ) > 0 );
assert( has_left_child( ) == true );
tree_clear( current_ptr->get_left( ) );
}
// remove_right_subtree
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::remove_right_subtree( )
{
assert( get_size( ) > 0 );
assert( has_right_child( ) == true );
tree_clear( current_ptr->get_right( ) );
}
// clear_tree
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::clear_tree( )
{
tree_clear( root_ptr );
current_ptr = NULL;
}
// shift_to_root
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::shift_to_root( )
{
assert( get_size( ) > 0 );
current_ptr = root_ptr;
}
// shift_left
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::shift_left( )
{
assert( has_left_child( ) == true );
current_ptr = current_ptr->get_left( );
}
// shift_right
//
// Library facilities used: binary_tree_node.h
//
template <typename Item>
void binary_tree<Item>::shift_right( )
{
assert( has_right_child( ) == true );
current_ptr = current_ptr->get_right( );
}
// print_tree
//
template <typename Item>
void binary_tree<Item>::print_tree(size_t depth)
{
print(root_ptr, depth);
}
/****************************************************/
/* OVERLOADED OPERATORS */
/****************************************************/
// =
//
// Library facilities used: binary_tree_node.h
template <typename Item>
void binary_tree<Item>::operator =(const binary_tree<Item>& source)
{
if (this == &source) // Handle self-assignment
return;
tree_clear(root_ptr);
root_ptr = tree_copy(source.root_ptr);
// where should current_ptr for new copy point?
// If copied an empty tree, current_ptr is NULL;
// otherwise, we'll start it at the root, I think.
if (root_ptr == NULL)
{
current_ptr = NULL;
}
else
{
current_ptr = root_ptr;
}
}