Please send questions to
st10@humboldt.edu .
/************************************************************/
/* ADAPTED 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, Ch.11 */
/************************************************************/
//-----------------------------------------------------------
// File: complete_tree.h
// Name: Michael Main, Walter Savitch
// (adapted by Sharon M. Tuttle)
// last modified: 4-13-05
//
// Template Class: complete_tree<Item> (a COMPLETE binary tree
// where each node contains an Item)
//
// Note that each non-empty complete_tree instance
// always has a "current node". The location of
// the current node is controlled by five
// member functions: shift_up, shift_to_root,
// shift_left, and shift_right, and
// shift_to_lowest_right
//
// VALUE SEMANTICS for the complete_tree<Item> template class:
// Assignments and the copy constructor may be used
// with complete_tree<Item> objects.
//
// DYNAMIC MEMORY USAGE by the complete_tree<Item> template class:
// If there is insufficient dynamic memory, then the
// following functions throw bad_alloc:
// create_root, add_left, add_right, the copy constructor,
// and the assignment operator.
//-----------------------------------------------------------
#ifndef COMPLETE_TREE_H
#define COMPLETE_TREE_H
#include <cstdlib> // Provides NULL and size_t
using namespace std;
template <typename Item>
class complete_tree
{
public:
/******************************************************/
/* TYPEDEFS and MEMBER CONSTANTS for the complete */
/* tree class */
/******************************************************/
// The template parameter, Item, is the data type of the
// items in the nodes of the complete_tree, also
// defined as complete_tree<Item>::value_type.
// It may be any of the C++ built-in types (int, char,
// etc.), or a class with a default constructor, a
// copy constructor, and an assignment operator.
//
typedef Item value_type;
/****************************************************/
/* CONSTRUCTORS and DESTRUCTOR */
/****************************************************/
// postcondition: creates an empty complete tree instance
// (with no nodes).
//
complete_tree( );
// copy constructor
//
complete_tree(const complete_tree<Item>& source);
// destructor
//
~complete_tree();
/*******************************************************/
/* ACCESSORS and other constant member functions */
/* (observers) */
/*******************************************************/
// postcondition: returns the number of nodes in the
// complete_tree.
//
size_t get_size( ) const;
// postcondition: returns true if the complete_tree is
// empty, returns false otherwise.
//
bool is_empty( ) const;
// precondition: size( ) > 0
// postcondition: returns (non-destructively) the data
// from the "current node", BUT the complete_tree is
// unchanged.
//
Item retrieve( ) const;
// postcondition: returns true if size( ) > 0 and
// and the "current node" is the root.
//
bool is_root( ) const;
// postcondition: returns true if size( ) > 0 and
// the "current node" is a leaf (has no children)
//
bool is_leaf( ) const;
// postcondition: returns true if size( ) > 0 and
// the "current node" has a parent.
//
bool has_parent( ) const;
// postcondition: returns true if size( ) > 0 and
// the "current node" has a left child.
//
bool has_left_child( ) const;
// postcondition: returns true if size( ) > 0 and
// the "current node" has a right child.
//
bool has_right_child( ) const;
// precondition: has_parent( ) == true
// postcondition: returns the value of "current
// node"'s parent
//
Item get_parent_value( ) const;
// precondition: has_left_child( ) == true
// postcondition: returns the value of the
// "current node"'s left child
//
Item get_left_value( ) const;
// precondition: has_right_child( ) == true
// postcondition: returns the value of the
// "current node"'s right child
//
Item get_right_value( ) const;
/****************************************************/
/* MODIFIERS and other modifying member functions */
/****************************************************/
// postconditions: a node has been added to the proper
// (next moving right) position at the lowest level
// to maintain this as a complete binary tree, with
// the given entry as its value.
// IF the tree was EMPTY before, then current node
// is now the root. Otherwise, current node
// is unchanged.
//
void add(const Item& entry);
// preconditions: size( ) > 0
// postconditions: the rightmost node on the lowest level
// of the tree has been removed, and its value is
// returned.
// IF the tree is now empty, then there is no longer
// a "current node"
// IF "current node" WAS the node to be removed, then
// "current node" is now that removed node's parent.
// OTHERWISE, "current_node" is unchanged.
//
Item remove( );
// precondition: size( ) > 0
// postcondition: the data at the "current node" has
// been changed to the new entry
//
void change(const Item& entry);
// postconditions: the tree is empty (and so there is
// no "current node")
//
void clear_tree( );
// precondition: size( ) > 0
// postcondition: the "current node" is now the root
// of the tree.
//
void shift_to_root( );
// precondition: has_parent( ) == true
// postcondition: the "current node" has been shifted
// up to the parent of the old current node.
//
void shift_up( );
// precondition: has_left_child( ) == true
// postcondition: the "current node" has been shifted
// down to the left child of the old current node.
//
void shift_left( );
// precondition: has_right_child( ) == true
// postcondition: the "current node" has been shifted
// down to the right child of the old current node.
//
void shift_right( );
// precondition: size( ) != 0
// postcondition: the "current node" has been shifted
// down to the rightmost item on the lowest level
//
void shift_to_lowest_right( );
// preconditions: if !empty( ), depth is the depth of the
// calling complete_tree instance.
// postconditions: if !empty, then the contents of the
// root and all of its descendants have been written to
// cout with the << operator using a backward in-order
// traversal. Each node is indented four times its depth.
//
void print_tree(size_t depth);
/****************************************************/
/* OVERLOADED OPERATORS */
/****************************************************/
// postcondition: the complete_tree that activated this
// will be made to have the same items as source
//
void operator =(const complete_tree<Item>& source);
private:
Item *nodes; // array of complete tree nodes
size_t capacity; // current capacity of the
// complete tree
size_t used; // current number of items in the
// complete tree
size_t current_index; // index of current node in tree
// helper function:
// get_parent_index
//
// precondition: has_parent( ) == true
// postcondition: returns index of current node's
// parent
//
size_t get_parent_index( ) const;
// helper function:
// get_left_index
//
// postcondition: returns what WOULD be index of
// current node's left child (BUT it may not
// currently exist!)
//
size_t get_left_index( ) const;
// helper function:
// get_right_index
//
// postcondition: returns what WOULD be index of
// current node's right child (BUT it may not
// currently exist!)
//
size_t get_right_index( ) const;
// helper function:
// print
//
// used to help accomplish print_tree
//
void print(size_t index, size_t depth);
};
#include "complete_tree.template" // Include the implementation
#endif