// Andrew C. White, acwhite@charter.net
// 19 April 2002
// Templated Binary Tree
// THIS CODE MAY BE USED BY ANYONE FOR ANY PURPOSE. BY USING THIS CODE YOU
// AGREE TO TAKE FULL RESPNSIBILITY FOR ANY HARMFUL OR UNINTENDED CONSEQUENCES
// THAT IT MAY CAUSE.
// NOTE: This code was created for maximum readability, and therefore is probably
// not very efficient.
// NOTE: The use of templates allows for extreme flexibility. Currently, only
// in-order traversal is implemented, however adding more traversal types would 
// be simple to do.
// NOTE: Before you can add data to a new tree, you must first call the SetIsGreater
// function. This must only be done once for the tree. The function you pass in must
// return a pointer to a BinTreeNode and take two parameters of the data type.
// See the included example if this is unclear.
// NOTE: Before you can use the in-order transversal, you must first call the
// SetInOrder function. This must only be done once for the tree. The function
// you pass in must take a single parameter of the data type. See the included 
// example if this is unclear.
  #ifndef _TBT_H_
#define _TBT_H_
  ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// TEMPLATED BINARY TREE NODE CLASS
template <class type> class BinTreeNode
{
public:
	BinTreeNode();
	~BinTreeNode();
  	BinTreeNode<type>* Add(type newData, bool (*isGreater) (type data1, type data2));
	void InOrder(void (*inOrder) (type data));
	
private:
	BinTreeNode<type>* right;
	BinTreeNode<type>* left;
	type data;
	bool full;
};
  // CONSTRUCTOR
template <class type> BinTreeNode<type>::BinTreeNode()
{
	right = 0;
	left = 0;
	full = false;
}
  // DECONSTRUCTOR
template <class type> BinTreeNode<type>::~BinTreeNode()
{
	if(left)
	{
		delete left;
		left = 0;
	}
  	if(right)
	{
		delete right;
		right = 0;
	}
}
  // ADD
template <class type> BinTreeNode<type>* BinTreeNode<type>::Add(type newData, bool (*isGreater)(type data1, type data2))
{
	if(full)
	{
		if(isGreater(newData, data))
		{
			if(!right)
				right = new BinTreeNode<type>;
			
			return right->Add(newData, isGreater);
		}
		else
		{
			if(!left)
				left = new BinTreeNode<type>;
  			return left->Add(newData, isGreater);
		}
	}
	else
	{
		data = newData;
		full = true;
		return this;
	}
}
  // IN-ORDER TRAVERSAL
template <class type> void BinTreeNode<type>::InOrder(void (*inOrder) (type data))
{
	if(left)
		left->InOrder(inOrder);
  	inOrder(this->data);
  	if(right)
		right->InOrder(inOrder);
}
  ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// TEMPLATED BINARY TREE CLASS
template <class type> class BinTree
{
public:
	BinTree();
	~BinTree();
  	BinTreeNode<type>* Add(type newData);
	void SetIsGreater(bool (*isGreater)(type data1, type data2));
	void InOrder();
	void SetInOrder(void (*inOrder) (type data));
  private:
	BinTreeNode<type>* root;
	bool (*isGreater) (type data1, type data2);
	void (*inOrder) (type data);
};
  // CONSTRUCTOR
template <class type> BinTree<type>::BinTree()
{
	root = 0;
	isGreater = 0;
}
  // DECONSTRUCTOR
template <class type> BinTree<type>::~BinTree()
{
	if(root)
	{
		delete root;
		root = 0;
	}
	
	isGreater = 0;
	inOrder = 0;
}
  // ADD
template <class type> BinTreeNode<type>* BinTree<type>::Add(type newData)
{
	if(!isGreater)
		return 0;
	
	if(!root)
		root = new BinTreeNode<type>;
	
    return root->Add(newData, isGreater);
}
  // SET THE COMPARE FUNCTION
template <class type> void BinTree<type>::SetIsGreater(bool (*isGreater) (type data1, type data2))
{
	this->isGreater = isGreater;
}
  // IN-ORDER TRAVERSAL
template <class type> void BinTree<type>::InOrder()
{
	if(root && inOrder)
		root->InOrder(inOrder);
}
  // SET THE IN-ORDER TRAVERSAL FUNCTION
template <class type> void BinTree<type>::SetInOrder(void (*inOrder) (type data))
{
	this->inOrder = inOrder;
}
  #endif   |