/* treesClass.cpp
 * 
 * Program defines a binary tree base class and a binary search tree
 * derived class.  The main() tests out the various class methods.
 *
 */


#include "treesClass.h"

// Silly little main() that lets user type in characters, and store
// them in a binary search tree.
// Tests out various binary (search) tree functions.
int main () {
   binarySearchTree mytree;
   char newch;

   cout << "Enter char: ";
   cin.get (newch);
   cin.get ();
   while (newch != '0') {
      mytree.insertItem (newch);
      cout << "Enter char: ";
      cin.get (newch);
      cin.get ();
   }

   cout << endl;
   cout << "Inorder traversal: ";
   mytree.inorderTraversal ();
   cout << endl << "Preorder traversal: ";
   mytree.preorderTraversal ();
   cout << endl << "Postorder traversal: ";
   mytree.postorderTraversal ();
   cout << endl << endl;

   cout << "Number of nodes : " << mytree.treeNodeCount() << endl;

   cout << endl;
   cout << "Enter search key: ";
   cin.get (newch);
   if (mytree.searchItem (newch))
      cout << newch << " found in tree" << endl;
   else
      cout << newch << " not found in tree" << endl;

   return 0;
}


/**********************binary search tree*****************************/
/**********************method definitions*****************************/


// Insert item into proper location in BST.
void binarySearchTree :: insertItem (elemType item)
{
   nodeType *cur;     // current node
   nodeType *parent;	// parent node
   nodeType *newNode; // node to insert

   newNode = new nodeType;
   assert (newNode);
   newNode->data = item;
   newNode->left = NULL;
   newNode->right = NULL;

   // first check if new node will be root
   if (root == NULL)
      root = newNode;

   else {
      // search for proper location
      cur = root;
      while (cur) {
         parent = cur;

	 if (item == cur->data) {
            cout << "Item already in tree; insert aborted." << endl;
	    return;
	 }
	 else if (item < cur->data)
	    cur = cur->left;
	 else
	    cur = cur->right;
      }

      // position located; now insert
      if (item < parent->data)
         parent->left = newNode;
      else
         parent->right = newNode;
   }
}


/*********************************************************************/


// Search for given key in BST.  Returns true if found, false otherwise.
bool binarySearchTree :: search (const elemType key, 
					   nodeType *p) const
{
   bool leftside, rightside;

   if (p) {
      if (p->data == key)
         return true;
      else {
	 leftside = search (key, p->left);
	 rightside = search (key, p->right);
	 return (leftside || rightside);
      }
   } else
      return false;
}


/*************************binary tree*********************************/
/**********************method definitions*****************************/


// Returns the number of nodes in binary tree.
int binaryTree :: nodecount (nodeType *p) const
{
   if (p) {
      return 1 + nodecount (p->left) + nodecount (p->right);
   } else
      return 0;
}


/*********************************************************************/


// Displays data in postorder; note that << operator must be overloaded
// if elemType is a user-defined type.
void binaryTree :: postorder (nodeType *p) const
{
   if (p) {
      postorder (p->left);
      postorder (p->right);
      cout << p->data << " ";
   }
}


/*********************************************************************/


// Displays data in inorder; note that << operator must be overloaded
// if elemType is a user-defined type.
void binaryTree :: inorder (nodeType * p) const
{
   if (p) {
      inorder (p->left);
      cout << p->data << " ";
      inorder (p->right);
   }
}


/*********************************************************************/


// Displays data in preorder; note that << operator must be overloaded
// if elemType is a user-defined type.
void binaryTree :: preorder(nodeType *p) const
{
   if (p) {
      cout << p->data << " ";
      preorder (p->left);
      preorder (p->right);
   }
}


/*********************************************************************/



// Returns the maximum of two integers.
int binaryTree :: max (int x, int y) const
{
   if (x < y)
      return y;
   else
      return x;
}
