Can anyone tell me why my last function height() causes the system to crash? I tested every function and they all work but when I coded this one and called it from main it causes the program to crash. It builds without any errors.
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
using namespace std;
// This class is a template class that creates a binary
// tree that can hold values of any data type. It has
// functions to insert a node, delete a node, display the
// tree In Order, Pre Order and Post Order, search for a
// value, count the number of total nodes, left nodes,
// and a function to determine the height of the tree.
template <class T>
class BinaryTree
{
private:
struct TreeNode
{
T value; // The value in the node
TreeNode *left; // Pointer to left child node
TreeNode *right; // Pointer to right child node
};
TreeNode *root; // Pointer to the root node
// Private member functions
void insert(TreeNode *&, TreeNode *&);
void destroySubTree(TreeNode *);
void deleteNode(T, TreeNode *&);
void makeDeletion(TreeNode *&);
void displayInOrder(TreeNode *) const;
void displayPreOrder(TreeNode *) const;
void displayPostOrder(TreeNode *) const;
int counter(TreeNode *);
int leafCounter(TreeNode *);
int height(TreeNode *);
public:
// Constructor
BinaryTree()
{ root = NULL; }
// Destructor
~BinaryTree()
{ destroySubTree(root); }
// Binary tree operations
void insertNode(T);
bool searchNode(T);
void remove(T);
void displayPreOrder() const
{ displayPreOrder(root); }
void displayInOrder() const
{ displayInOrder(root); }
void displayPostOrder() const
{ displayPostOrder(root); }
// Node counter
int counter()
{
int n = counter(root);
return n;
}
// Leaf counter
int leafCounter()
{
int leaf = leafCounter(root);
return leaf;
}
// Height of the tree
int height()
{
int h = height(root);
return h;
}
};
//*********************************************************
// insert function accepts a TreeNode pointer and a *
// pointer to a node. The function inserts the node into *
// the tree pointer to by the TreeNode pointer. This *
// function is call recursively. *
//*********************************************************
template <class T>
void BinaryTree<T>::insert(TreeNode *&nodePtr, TreeNode *&newNode)
{
if (nodePtr == NULL)
nodePtr = newNode; // Insert the node
else if (newNode->value < nodePtr->value)
insert(nodePtr->left, newNode); // Search the left branch
else
insert(nodePtr->right, newNode);// Search the right branch
}
//*********************************************************
// insertNode creates anew node to hold num as its value *
// and passes it to the insert function. *
//*********************************************************
template <class T>
void BinaryTree<T>::insertNode(T item)
{
TreeNode *newNode; // Pointer to a new node
// Create anew node and store num in it
newNode = new TreeNode;
newNode->value = item;
newNode->left = newNode->right = NULL;
// Insert the node
insert(root, newNode);
}
//**********************************************************
// destroySubTree is called by the destructor. It deletes *
// all nodes in the tree. *
//**********************************************************
template <class T>
void BinaryTree<T>::destroySubTree(TreeNode *nodePtr)
{
if (nodePtr)
{
if (nodePtr->left)
destroySubTree(nodePtr->left);
if (nodePtr->right)
destroySubTree(nodePtr->right);
delete nodePtr;
}
}
//**********************************************************
// searchNode determines if a value is present in the tree.*
// If so, the function returns true. Otherwise it returns *
// false.
//**********************************************************
template <class T>
bool BinaryTree<T>::searchNode(T item)
{
TreeNode *nodePtr = root;
while (nodePtr)
{
if (nodePtr->value == item)
return true;
else if (item < nodePtr->value)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
//*********************************************************
// remove calls deleteNode to delete the node whode value *
// member is the same as num *
//*********************************************************
template <class T>
void BinaryTree<T>::remove(T item)
{
deleteNode(item, root);
}
//*********************************************************
// deleteNode deletes the node whose value member is the *
// same as num *
//*********************************************************
template <class T>
void BinaryTree<T>::deleteNode(T item, TreeNode *&nodePtr)
{
if (item < nodePtr->value)
deleteNode(item, nodePtr->left);
else if (item > nodePtr->value)
deleteNode(item, nodePtr->right);
else
makeDeletion(nodePtr);
}
//*********************************************************
// makeDeletion takes a reference to apointer to the node *
// that is to be deleted. The node is removed and the *
// branches of the tree below the node are reattached *
//*********************************************************
template <class T>
void BinaryTree<T>::makeDeletion(TreeNode *&nodePtr)
{
// Define a temporary pointer to use in reattaching
// the left subtree
TreeNode *tempNodePtr;
if (nodePtr == NULL)
cout << "Cannot delete empty node.\n";
else if (nodePtr->right == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->left; // Reattach the left child
delete tempNodePtr;
}
else if (nodePtr->left == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // Reattach the right child
delete tempNodePtr;
}
}
//*********************************************************
// The displayInOrder function displays the values in the *
// subtree pointed to by nodePtr, via inorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayInOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
displayInOrder(nodePtr->left);
cout << nodePtr->value << endl;
displayInOrder(nodePtr->right);
}
}
//*********************************************************
// The displayPreOrder function displays the values in the*
// subtree pointed to by nodePtr, via Preorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayPreOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
cout << nodePtr->value << endl;
displayInOrder(nodePtr->left);
displayInOrder(nodePtr->right);
}
}
//*********************************************************
// displayPostOrder function displays the values in the *
// subtree pointed to by nodePtr, via Postorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayPostOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
displayInOrder(nodePtr->left);
displayInOrder(nodePtr->right);
cout << nodePtr->value << endl;
}
}
//*********************************************************
// counter counts the number of nodes the tree has *
//*********************************************************
template <class T>
int BinaryTree<T>::counter(TreeNode *nodePtr)
{
if (nodePtr == NULL)
return 0;
else
return counter(nodePtr->left) +1+ counter(nodePtr->right);
}
//*********************************************************
// leafCounter counts the number of leaf nodes in the tree*
//*********************************************************
template <class T>
int BinaryTree<T>::leafCounter(TreeNode *nodePtr)
{
if (nodePtr == NULL)
return 0;
else if (nodePtr->left == NULL && nodePtr->right == NULL)
return 1;
else
return leafCounter(nodePtr->left) + leafCounter(nodePtr->right);
}
//*********************************************************
// height returns the height of the tree *
//*********************************************************
template <class T>
int BinaryTree<T>::height(TreeNode *nodePtr)
{
if(nodePtr = NULL)
return -1;
if (height(nodePtr->left) <= height(nodePtr->right))
return (height(nodePtr->right) +1);
else
return (height(nodePtr->left) +1);
}
#endif
Main
// This program demonstrates that the functions of
// BinaryTree works correctly.
#include "BinaryTree.h"
#include <iostream>
using namespace std;
int main()
{
// Create a BinaryTree object
BinaryTree<int> tree;
// Insert some nodes
cout << "Inserting nodes...\n";
tree.insertNode(5);
tree.insertNode(10);
tree.insertNode(3);
tree.insertNode(1);
tree.insertNode(13);
// Display the nodes InOrder
cout << "\nDisplaying the nodes InOrder...\n";
tree.displayInOrder();
// Display the nodes PreOrder
cout << "\nDisplaying the nodes PreOrder...\n";
tree.displayPreOrder();
// Display the nodes PostOrder
cout << "\nDisplaying the nodes PostOrder...\n";
tree.displayPostOrder();
// Delete a node
cout << "\nDeleting node 3...\n";
tree.remove(3);
// Display the nodes after deletion
cout << "\nHere are the nodes InOrder after deletion:\n";
tree.displayInOrder();
// Search the nodes for the value 10
cout << "\nSearching the nodes for the value 10...\n";
if (tree.searchNode(10))
cout << "Value was found.\n";
else
cout << "Value was not found.\n";
// Search for the deleted node 3
cout << "\nSearching for the deleted node 3...\n";
if (tree.searchNode(3))
cout << "Value was found.\n";
else
cout << "Value was not found.\n";
// Count how many nodes are in the tree
cout << "\nThere are " << tree.counter() << " nodes"
<< " in the tree.\n";
// Count how many leafs are in the tree
cout << "\nThere are " << tree.leafCounter()
<< " leaves in the tree.\n";
// Get the height of the tree
cout << "\nThe height of the tree is " << tree.height();
cout << endl;
return 0;
}
if(nodePtr = NULL)
should be:
if(nodePtr == NULL)
The first one sets nodePtr to NULL, then implicitly tests if the result is not NULL (which is always false). The second one tests whether nodePtr is NULL.
Related
My problem is trying to get functions treeLeavesCount() and treeNodeCount() to return a value of leaves and nodes in the tree but, my issue is after providing values through a while loop using an insert() function, the tree seems to stay empty and I know this by using an isEmpty() function before and after inserting values into the tree.
main.cpp
#include <iostream>
#include "binaryTreeType.h"
#include "bSearchTreeType.h"
using namespace std;
int main()
{
int num;
bSearchTreeType<int> *myTree= new bSearchTreeType<int>();
//test if tree is empty
if(myTree->isEmpty())
cout << "yes" << endl;
else
cout << "no" << endl;
cout << "Line 10: Enter numbers ending with -999"<< endl;
cin >> num;
while (num != -999)
{
myTree->insert(num);
cin >> num;
}
myTree->inorderTraversal();
int p;
p=myTree->treeNodeCount();
cout << p << endl;
p=myTree->treeLeavesCount();
cout << p << endl;
//test if tree is empty after data is inserted
if(myTree->isEmpty())
cout << "yes" << endl;
else
cout << "no" << endl;
delete myTree;
return 0;
}
binaryTreeType.h
#ifndef BINARYTREETYPE_H
#define BINARYTREETYPE_H
#include <queue>
template <class elemType>
struct binaryTreeNode
{
elemType info;
binaryTreeNode<elemType> *llink;
binaryTreeNode<elemType> *rlink;
};
template <class elemType>
class binaryTreeType
{
public:
const binaryTreeType<elemType>& operator=(const binaryTreeType<elemType>&);
//Overload the assignment operator.
bool isEmpty() const;
//Returns true if the binary tree is empty;
//otherwise, returns false.
void inorderTraversal() const;
//Function to do an inorder traversal of the binary tree.
void preorderTraversal() const;
//Function to do a preorder traversal of the binary tree.
void postorderTraversal() const;
//Function to do a postorder traversal of the binary tree.
int treeHeight() const;
//Returns the height of the binary tree.
int treeNodeCount() const;
//Returns the number of nodes in the binary tree.
int treeLeavesCount() const;
//Returns the number of leaves in the binary tree.
void destroyTree();
//Deallocates the memory space occupied by the binary tree.
//Postcondition: root = NULL;
binaryTreeType(const binaryTreeType<elemType>& otherTree);
//copy constructor
binaryTreeType();
//default constructor
~binaryTreeType();
//destructor
protected:
binaryTreeNode<elemType> *root;
private:
void copyTree(binaryTreeNode<elemType>* &copiedTreeRoot,binaryTreeNode<elemType>* otherTreeRoot);
//Makes a copy of the binary tree to which
//otherTreeRoot points. The pointer copiedTreeRoot
//points to the root of the copied binary tree.
void destroy(binaryTreeNode<elemType>* &p);
//Function to destroy the binary tree to which p points.
//Postcondition: p = NULL
void inorder(binaryTreeNode<elemType> *p) const;
//Function to do an inorder traversal of the binary
//tree to which p points.
void preorder(binaryTreeNode<elemType> *p) const;
//Function to do a preorder traversal of the binary
//tree to which p points.
void postorder(binaryTreeNode<elemType> *p) const;
//Function to do a postorder traversal of the binary
//tree to which p points.
int height(binaryTreeNode<elemType> *p) const;
//Function to return the height of the binary tree
//to which p points.
int max(int x, int y) const;
//Returns the larger of x and y.
int nodeCount(binaryTreeNode<elemType> *p) const;
//Function to return the number of nodes in the binary
//tree to which p points
int leavesCount(binaryTreeNode<elemType> *p) const;
//Function to return the number of leaves in the binary
//tree to which p points
};
template <class elemType>
bool binaryTreeType<elemType>::isEmpty() const
{
return (root == NULL);
};
template <class elemType>
binaryTreeType<elemType>::binaryTreeType()
{
root = NULL;
}
template <class elemType>
void binaryTreeType<elemType>::inorderTraversal() const
{
inorder(root);
}
template <class elemType>
void binaryTreeType<elemType>::preorderTraversal() const
{
preorder(root);
}
template <class elemType>
void binaryTreeType<elemType>::postorderTraversal() const
{
postorder(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeHeight() const
{
return height(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeNodeCount() const
{
return nodeCount(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeLeavesCount() const
{
return leavesCount(root);
}
template <class elemType>
void binaryTreeType<elemType>::inorder(binaryTreeNode<elemType> *p) const
{
if (p != NULL)
{
inorder(p->llink);
std::cout << p->info << " ";
inorder(p->rlink);
}
}
template <class elemType>
void binaryTreeType<elemType>::preorder(binaryTreeNode<elemType> *p) const
{
if (p != NULL)
{
std::cout << p->info << " ";
preorder(p->llink);
preorder(p->rlink);
}
}
template <class elemType>
void binaryTreeType<elemType>::postorder(binaryTreeNode<elemType> *p) const
{
if (p != NULL)
{
postorder(p->llink);
postorder(p->rlink);
std::cout << p->info << " ";
}
}
template <class elemType>
int binaryTreeType<elemType>::height(binaryTreeNode<elemType> *p) const
{
if (p == NULL)
return 0;
else
return 1 + max(height(p->llink), height(p->rlink));
}
template <class elemType>
int binaryTreeType<elemType>::max(int x, int y) const
{
if (x >= y)
return x;
else
return y;
}
template <class elemType>
void binaryTreeType<elemType>::copyTree(binaryTreeNode<elemType>* &copiedTreeRoot,binaryTreeNode<elemType>* otherTreeRoot)
{
if (otherTreeRoot == NULL)
copiedTreeRoot = NULL;
else
{
copiedTreeRoot = new binaryTreeNode<elemType>;
copiedTreeRoot->info = otherTreeRoot->info;
copyTree(copiedTreeRoot->llink, otherTreeRoot->llink);
copyTree(copiedTreeRoot->rlink, otherTreeRoot->rlink);
}
} //end copyTree
template <class elemType>
void binaryTreeType<elemType>::destroy(binaryTreeNode<elemType>* &p)
{
if (p != NULL)
{
destroy(p->llink);
destroy(p->rlink);
delete p;
p = NULL;
}
}
template <class elemType>
void binaryTreeType<elemType>::destroyTree()
{
destroy(root);
}
template <class elemType>
binaryTreeType<elemType>::binaryTreeType(const binaryTreeType<elemType>& otherTree)
{
if (otherTree.root == NULL) //otherTree is empty
root = NULL;
else
copyTree(root, otherTree.root);
}
template <class elemType>
binaryTreeType<elemType>::~binaryTreeType()
{
destroy(root);
}
template <class elemType>
const binaryTreeType<elemType>& binaryTreeType<elemType>::operator=(const binaryTreeType<elemType>& otherTree)
{
if (this != &otherTree) //avoid self-copy
{
if (root != NULL) //if the binary tree is not empty,
//destroy the binary tree
destroy(root);
if (otherTree.root == NULL) //otherTree is empty
root = NULL;
else
copyTree(root, otherTree.root);
}//end else
return *this;
}
template <class elemType>
int binaryTreeType<elemType>::leavesCount(binaryTreeNode<elemType> *p) const
{
if(p == NULL)
return 0;
if(p->llink == NULL && p->rlink==NULL)
return 1;
else
return leavesCount(p->llink) + leavesCount(p->rlink);
}
template <class elemType>
int binaryTreeType<elemType> ::nodeCount(binaryTreeNode<elemType> *p) const
{
int count = 1;
if ( p == NULL ){
return 0;
}else{
count += nodeCount(p->llink);
count += nodeCount(p->rlink);
}
return count;
}
#endif // BINARYTREETYPE_H
bSearchTreeType.h
#ifndef BSEARCHTREETYPE_H
#define BSEARCHTREETYPE_H
#include "binaryTreeType.h"
#include <iostream>
#include <cassert>
template <class elemType>
class bSearchTreeType : public binaryTreeType<elemType>
{
public:
bool search(const elemType& searchItem) const;
//Function to determine if searchItem is in the binary
//search tree.
//Postcondition: Returns true if searchItem is found in the
// binary search tree; otherwise, returns false.
void insert(const elemType& insertItem);
//Function to insert insertItem in the binary search tree.
//Postcondition: If no node in the binary search tree has the
// same info as insertItem, a node with the info insertItem
// is created and inserted in the binary search tree.
void deleteNode(const elemType& deleteItem);
//Function to delete deleteItem from the binary search tree.
//Postcondition: If a node with the same info as deleteItem
// is found, it is deleted from the binary search tree.
protected:
binaryTreeNode<elemType> *root;
private:
void deleteFromTree(binaryTreeNode<elemType>* &p);
//Function to delete the node to which p points is deleted
//from the binary search tree.
//Postcondition: The node to which p points is deleted from
// the binary search tree.
};
using namespace std;
template <class elemType>
bool bSearchTreeType<elemType>::search(const elemType& searchItem) const
{
binaryTreeNode<elemType> *current;
bool found = false;
if (root == NULL)
cerr << "Cannot search the empty tree." << endl;
else
{
current = root;
while (current != NULL && !found)
{
if (current->info == searchItem)
found = true;
else if (current->info > searchItem)
current = current->llink;
else
current = current->rlink;
}//end while
}//end else
return found;
}//end search
template <class elemType>
void bSearchTreeType<elemType>::insert(const elemType& insertItem)
{
binaryTreeNode<elemType> *current; //pointer to traverse the tree
binaryTreeNode<elemType> *trailCurrent; //pointer behind current
binaryTreeNode<elemType> *newNode; //pointer to create the node
newNode = new binaryTreeNode<elemType>;
assert(newNode != NULL);
newNode->info = insertItem;
newNode->llink = NULL;
newNode->rlink = NULL;
if (root == NULL)
root = newNode;
else
{
current = root;
while (current != NULL)
{
trailCurrent = current;
if (current->info == insertItem)
{
std::cerr << "The insert item is already in the list-";
std::cerr << "duplicates are not allowed." << insertItem << std::endl;
return;
}
else if (current->info > insertItem)
current = current->llink;
else
current = current->rlink;
}//end while
if (trailCurrent->info > insertItem)
trailCurrent->llink = newNode;
else
trailCurrent->rlink = newNode;
}
}//end insert
template <class elemType>
void bSearchTreeType<elemType>::deleteFromTree(binaryTreeNode<elemType>* &p)
{
binaryTreeNode<elemType> *current;//pointer to traverse the tree
binaryTreeNode<elemType> *trailCurrent; //pointer behind current
binaryTreeNode<elemType> *temp; //pointer to delete the node
if (p == NULL)
cerr << "Error: The node to be deleted is NULL." << endl;
else if(p->llink == NULL && p->rlink == NULL)
{
temp = p;
p = NULL;
delete temp;
}
else if(p->llink == NULL)
{
temp = p;
p = temp->rlink;
delete temp;
}
else if(p->rlink == NULL)
{
temp = p;
p = temp->llink;
delete temp;
}
else
{
current = p->llink;
trailCurrent = NULL;
while (current->rlink != NULL)
{
trailCurrent = current;
current = current->rlink;
}//end while
p->info = current->info;
if (trailCurrent == NULL) //current did not move;
//current == p->llink; adjust p
p->llink = current->llink;
else
trailCurrent->rlink = current->llink;
delete current;
}//end else
}//end deleteFromTree
template <class elemType>
void bSearchTreeType<elemType>::deleteNode(const elemType& deleteItem)
{
binaryTreeNode<elemType> *current; //pointer to traverse the tree
binaryTreeNode<elemType> *trailCurrent; //pointer behind current
bool found = false;
if (root == NULL)
std::cout << "Cannot delete from the empty tree." << endl;
else
{
current = root;
trailCurrent = root;
while (current != NULL && !found)
{
if (current->info == deleteItem)
found = true;
else
{
trailCurrent = current;
if (current->info > deleteItem)
current = current->llink;
else
current = current->rlink;
}
}//end while
if (current == NULL)
std::cout << "The delete item is not in the tree." << endl;
else if (found)
{
if (current == root)
deleteFromTree(root);
else if (trailCurrent->info > deleteItem)
deleteFromTree(trailCurrent->llink);
else
deleteFromTree(trailCurrent->rlink);
}//end if
}
}//end deleteNode
#endif // BSEARCHTREETYPE_H
(That's a humongous amount of code. Please remove everything your test case doesn't need next time.)
Cutting your code down to the bare essentials, we get
template <class elemType>
class binaryTreeType
{
public:
bool isEmpty() const;
protected:
binaryTreeNode<elemType> *root;
};
template <class elemType>
bool binaryTreeType<elemType>::isEmpty() const
{
return (root == NULL);
};
template <class elemType>
class bSearchTreeType : public binaryTreeType<elemType>
{
void insert(const elemType& insertItem);
protected:
binaryTreeNode<elemType> *root;
};
template <class elemType>
void bSearchTreeType<elemType>::insert(const elemType& insertItem)
{
// ...
if (root == NULL)
root = newNode;
else
{
current = root;
//...
}
}//end insert
And now we can see that you declare two member variables called "root".
The one in bSearchTreeType hides the one in binaryTreeType - it's not a redeclaration or "override" of the same variable.
This means that your binaryTreeType member functions (such as isEmpty) use the root in binaryTreeType, while the member functions of bSearchTreeType (such as insert) use the root in bSearchTreeType, so after insert has updated one of the roots the other one is still null.
Incidentally, this issue is also difficult to discover with a debugger, where you'll just be staring at a variable whose value changes as if by magic.
You need to do two things:
Remove the root member from bSearchTreeType
Because these are templates, you also need to change root to this->root in the bSearchTreeType member functions. (Finding out why left as an exercise - it's an essay of its own.)
(It seems to work with just these changes, by the way. Well done.)
is it possible to write a function to return the parent node of a given node for a binary tree?
BinaryTree *search_val(BinaryTree *bt, int val)
{
//temp pointer
BinaryTree* temp = NULL;
if(!bt->isEmpty())
{
//check if root is equal to value and return root if true
if(bt->getData() == val)
{
return bt;
}
else
{
//search left side
temp = search_val(bt->left(), val);
//if not found in left, search right
if (temp == NULL)
{
temp = search_val(bt->right(), val);
}
return temp;
}
return NULL;
}
return NULL;
}
I just have this search function at the moment. I got it from here actually. So I'm trying to convert this to search for the parent of a node. The parameters will be the root node and the node whose parent we want. Is that even possible?
I just need some hints to get started then I'll post my code. The purpose of creating this function is because I have a delete leaf node function that works almost perfectly....the only problem is that when I print all nodes after deleting, the supposedly deleted node still appears. I'm sure it's because the parent node is still linked to it in main. Here's my delete leaf node function:
void delete_leaf_node(BinaryTree *bt, int val)
{
BinaryTree *temp;
temp = search_val(bt, val);
//If node does not exist in the tree, inform the user
if(temp == NULL)
{
cout << "\n " << val << " was not found in the tree" << endl;
}
//Check if node is a leaf
else if(temp->isLeaf())
{
delete temp;
cout << "\n Leaf " << temp->getData() << " deleted" << endl;
}
//Inform user that node is not a leaf
else
cout << "\n " << temp->getData() << " is not a Leaf" << endl;
//Display using In Order Traversal to see that the node was actually deleted
cout << "\n In Order Traversal after deleting: " << endl << "\n ";
inOrderTraverse(bt);
cout << endl;
}
I hope I'm making sense to someone...sorry I tried to shorten the question but couldn't.
BinaryTree.h file:
using namespace std;
//BinaryTree class
class BinaryTree{
public:
BinaryTree();
bool isEmpty();
bool isLeaf();
int getData();
void insert(const int &DATA);
BinaryTree *left();
BinaryTree *right();
void makeLeft(BinaryTree *bt);
void makeRight(BinaryTree *bt);
private:
bool nullTree;
int treeData;
BinaryTree *leftTree;
BinaryTree *rightTree;
};
BinaryTree.cpp file:
#include <iostream>
#include "BinaryTree.h"
using namespace std;
//constructor
BinaryTree::BinaryTree()
{
nullTree = true;
leftTree = NULL;
rightTree = NULL;
}
/*
is_empty function for BinaryTree class. Does not take any parameters.
Returns true if tree is empty and false otherwise.
*/
bool BinaryTree::isEmpty()
{
return nullTree;
}
/*
is_leaf function for BinaryTree class. Does not take any parameters.
Returns true if node has no children and false otherwise.
*/
bool BinaryTree::isLeaf()
{
return ((this->leftTree->treeData == 0) && (this->rightTree->treeData == 0));
}
/*
getData function for BinaryTree class. Does not take any parameters.
Returns treeData value.
*/
int BinaryTree::getData()
{
if(!isEmpty());
return treeData;
}
/*
insert function for BinaryTree class. Takes one parameter, passed by
reference. Returns true if node has no children and false otherwise.
*/
void BinaryTree::insert(const int &DATA)
{
//create empty children and insert DATA
treeData = DATA;
if(nullTree)
{
nullTree = false;
leftTree = new BinaryTree;
rightTree = new BinaryTree;
}
}
/*
left function for BinaryTree class. It points to the left node.
Does not take any parameters. Returns left node.
*/
BinaryTree *BinaryTree::left()
{
if(!isEmpty());
return leftTree;
}
/*
right function for BinaryTree class. It points to the right node.
Does not take any parameters. Returns right node.
*/
BinaryTree *BinaryTree::right()
{
if(!isEmpty());
return rightTree;
}
/*
makeLeft function for BinaryTree class. Takes a pointer to a tree node as a parameter.
makes the parameter the left child of a node. Does not return any value
*/
void BinaryTree::makeLeft(BinaryTree *bt)
{
if(!isEmpty());
leftTree = bt;
}
/*
makeRight function for BinaryTree class. Takes a pointer to a tree node as a parameter.
makes the parameter the right child of a node. Does not return any value
*/
void BinaryTree::makeRight(BinaryTree *bt)
{
if (!isEmpty());
rightTree = bt;
}
Thanks
That depends on your BinaryTree implementation. As far as I see, if you don't save a reference inside each node to his parent, you can't directly access to it when deleting
Edit
You can modify your BinaryTree class with:
class BinaryTree{
public:
BinaryTree();
bool isEmpty();
bool isLeaf();
int getData();
void insert(const int &DATA);
BinaryTree *left();
BinaryTree *right();
void makeLeft(BinaryTree *bt);
void makeRight(BinaryTree *bt);
void setParent(BinaryTree *parent);
BinaryTree* getParent();
private:
bool nullTree;
int treeData;
BinaryTree *leftTree;
BinaryTree *rightTree;
BinaryTree* parent;
};
Then in your .cpp:
BinaryTree::BinaryTree()
{
nullTree = true;
leftTree = NULL;
rightTree = NULL;
parent = NULL;
}
void BinaryTree::setParent(BinaryTree *parent){
this->parent = parent;
}
BinaryTree* BinaryTree::getParent(){
return parent;
}
Your delete function will look like:
void delete_leaf_node(BinaryTree *bt, int val)
{
BinaryTree *temp;
temp = search_val(bt, val);
//If node does not exist in the tree, inform the user
if(temp == NULL)
{
cout << "\n " << val << " was not found in the tree" << endl;
}
//Check if node is a leaf
else if(temp->isLeaf())
{
// You must distinguish which child you are
BinaryTree* parent = temp->getParent();
BinaryTree* leftChild = parent->left;
BinaryTree* rightChild = parent->right;
if(leftChild == temp){
parent->left = null;
}
if(rightChild == temp){
parent->right = null;
}
delete temp;
cout << "\n Leaf " << temp->getData() << " deleted" << endl;
}
//Inform user that node is not a leaf
else
cout << "\n " << temp->getData() << " is not a Leaf" << endl;
//Display using In Order Traversal to see that the node was actually deleted
cout << "\n In Order Traversal after deleting: " << endl << "\n ";
inOrderTraverse(bt);
cout << endl;
}
This code runs fine without errors, but I can not figure out how to get the level of the binary tree without knowing the actual numbers of each node. I currently have a for loop which I know is not correct, but I don't know how to find out the level of the binary tree. I also want to see if I can find out all nodes that have one child.
#ifndef BINARYTREE_H
#define BINARYTREE_H
class BinaryTree
{
private:
struct TreeNode
{
int value;
TreeNode *left;
TreeNode *right;
}; TreeNode *root;
void insert(TreeNode *&, TreeNode *&);
void destroySubTree(TreeNode *);
void deleteNode(int, TreeNode *&);
void makeDeletion(TreeNode *&);
void displayInOrder(TreeNode *) const;
void displayPreOrder(TreeNode *) const;
void displayPostOrder(TreeNode *) const;
public:
// Constructor
BinaryTree()
{
root = nullptr;
}
// Destructor
~BinaryTree()
{
destroySubTree(root);
}
// Binary tree operations
void insertNode(int);
bool searchNode(int);
void remove(int);
void displayInOrder() const
{
displayInOrder(root);
}
void displayPreOrder() const
{
displayPreOrder(root);
}
void displayPostOrder() const
{
displayPostOrder(root);
}
int countNodes(TreeNode *);
void count();
int getLevelTree(TreeNode *, int, int);
int getLevel(int);
};
#endif
#include <iostream>
#include<cmath>
#include "BinaryTree.h"
using namespace std;
// insert accepts a TreeNode pointer and a pointer to a node. The function inserts the node into
// the tree pointed to by the TreeNode pointer. This function is called recursively.
void BinaryTree::insert(TreeNode *&nodePtr, TreeNode *&newNode)
{
if (nodePtr == NULL)
nodePtr = newNode; // Insert the node.
else if (newNode->value < nodePtr->value)
insert(nodePtr->left, newNode); // Search the left branch
else
insert(nodePtr->right, newNode); // Search the right branch
}
// insertNode creates a new node to hold num as its value, and passes it to the insert function.
void BinaryTree::insertNode(int num)
{
TreeNode *newNode; // Pointer to a new node.
// Create a new node and store num in it.
newNode = new TreeNode;
newNode->value = num;
newNode->left = newNode->right = NULL;
// Insert the node.
insert(root, newNode);
}
// destroySubTree is called by the destructor. It deletes all nodes in the tree.
void BinaryTree::destroySubTree(TreeNode *nodePtr)
{
if (nodePtr)
{
if (nodePtr->left)
destroySubTree(nodePtr->left);
if (nodePtr->right)
destroySubTree(nodePtr->right);
delete nodePtr;
}
}
// searchNode determines if a value is present in the tree.
// If so, the function returns true. Otherwise, it returns false.
bool BinaryTree::searchNode(int num)
{
TreeNode *nodePtr = root;
while (nodePtr)
{
if (nodePtr->value == num)
return true;
else if (num < nodePtr->value)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
// remove calls deleteNode to delete the node whose value member is the same as num.
void BinaryTree::remove(int num)
{
deleteNode(num, root);
}
// deleteNode deletes the node whose value member is the same as num.
void BinaryTree::deleteNode(int num, TreeNode *&nodePtr)
{
if (num < nodePtr->value)
deleteNode(num, nodePtr->left);
else if (num > nodePtr->value)
deleteNode(num, nodePtr->right);
else
makeDeletion(nodePtr);
}
// makeDeletion takes a reference to a pointer to the node that is to be deleted.
// The node is removed and the branches of the tree below the node are reattached.
void BinaryTree::makeDeletion(TreeNode *&nodePtr)
{
// Define a temporary pointer to use in reattaching
// the left subtree.
TreeNode *tempNodePtr;
if (nodePtr == NULL)
cout << "Cannot delete empty node.\n";
else if (nodePtr->right == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->left; // Reattach the left child
delete tempNodePtr;
}
else if (nodePtr->left == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // Reattach the right child
delete tempNodePtr;
}
// If the node has two children.
else
{
// Move one node the right.
tempNodePtr = nodePtr->right;
// Go to the end left node.
while (tempNodePtr->left)
tempNodePtr = tempNodePtr->left;
// Reattach the left subtree.
tempNodePtr->left = nodePtr->left;
tempNodePtr = nodePtr;
// Reattach the right subtree.
nodePtr = nodePtr->right;
delete tempNodePtr;
}
}
// The displayInOrder member function displays the values
// in the subtree pointed to by nodePtr, via inorder traversal.
void BinaryTree::displayInOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
displayInOrder(nodePtr->left);
cout << nodePtr->value << endl;
displayInOrder(nodePtr->right);
}
}
// The displayPreOrder member function displays the values
// in the subtree pointed to by nodePtr, via preorder traversal.
void BinaryTree::displayPreOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
cout << nodePtr->value << endl;
displayPreOrder(nodePtr->left);
displayPreOrder(nodePtr->right);
}
}
// The displayPostOrder member function displays the values
// in the subtree pointed to by nodePtr, via postorder traversal.
void BinaryTree::displayPostOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
displayPostOrder(nodePtr->left);
displayPostOrder(nodePtr->right);
cout << nodePtr->value << endl;
}
}
int BinaryTree::getLevelTree(TreeNode *node, int val, int lev)
{
if (node == NULL)
{
return 0;
}
if (node->value == val)
{
return lev;
}
int downlev = getLevelTree(node->left, val, lev + 1);
return downlev;
}
int BinaryTree::getLevel(int val)
{
return getLevelTree(root, val, 1);
}
int BinaryTree::countNodes(TreeNode *root)
{
if (root == NULL)
{
return 0;
}
else
{
int count = 1;
count += countNodes(root->left);
count += countNodes(root->right);
return count;
}
}
void BinaryTree::count()
{
cout<< countNodes(root);
}
#include <iostream>
#include<vector>
#include<algorithm>
#include<cstdlib>
#include<numeric>
#include<ctime>
#include "BinaryTree.h"
using namespace std;
int main()
{
int randNum;
vector<int> randData;
vector<int>::iterator iter;
size_t size = randData.size();
srand(time(0));
BinaryTree tree;
for (int i = 0; i < 5; i++)
{
randNum = rand() % 1000 + 1;
tree.insertNode(randNum);
}
cout << "display : \n";
tree.displayInOrder();
cout << endl;
for(int i=1; i<=5;i++)
{
cout<< "getlevel: "<<tree.getLevel(i);
}
system("pause");
return 0;
}
The program should ask the user to enter the ID number of the employee he or she wants to search for. If it is found the employee of that ID number is displayed. I can display the ID numbers and employees just by using the display functions but I can't figure out how to make the search function work and display the employees.
BINARYTREE
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
using namespace std;
// This class is a template class that creates a binary
// tree that can hold values of any data type. It has
// functions to insert a node, delete a node, display the
// tree In Order, Pre Order and Post Order, search for a
// value, count the number of total nodes, left nodes,
// and a function to determine the height of the tree.
template <class T>
class BinaryTree
{
private:
struct TreeNode
{
T value; // The value in the node
TreeNode *left; // Pointer to left child node
TreeNode *right; // Pointer to right child node
};
TreeNode *root; // Pointer to the root node
// Private member functions
void insert(TreeNode *&, TreeNode *&);
void destroySubTree(TreeNode *);
void deleteNode(T, TreeNode *&);
void makeDeletion(TreeNode *&);
void displayInOrder(TreeNode *) const;
void displayPreOrder(TreeNode *) const;
void displayPostOrder(TreeNode *) const;
public:
// Constructor
BinaryTree()
{ root = NULL; }
// Destructor
~BinaryTree()
{ destroySubTree(root); }
// Binary tree operations
void insertNode(T);
bool searchNode(int);
void remove(T);
void displayPreOrder() const
{ displayPreOrder(root); }
void displayInOrder() const
{ displayInOrder(root); }
void displayPostOrder() const
{ displayPostOrder(root); }
};
//*********************************************************
// insert function accepts a TreeNode pointer and a *
// pointer to a node. The function inserts the node into *
// the tree pointer to by the TreeNode pointer. This *
// function is call recursively. *
//*********************************************************
template <class T>
void BinaryTree<T>::insert(TreeNode *&nodePtr, TreeNode *&newNode)
{
if (nodePtr == NULL)
nodePtr = newNode; // Insert the node
else if (newNode->value < nodePtr->value)
insert(nodePtr->left, newNode); // Search the left branch
else
insert(nodePtr->right, newNode);// Search the right branch
}
//*********************************************************
// insertNode creates a new node to hold item as its value*
// and passes it to the insert function. *
//*********************************************************
template <class T>
void BinaryTree<T>::insertNode(T item)
{
TreeNode *newNode; // Pointer to a new node
// Create anew node and store num in it
newNode = new TreeNode;
newNode->value = item;
newNode->left = newNode->right = NULL;
// Insert the node
insert(root, newNode);
}
//**********************************************************
// destroySubTree is called by the destructor. It deletes *
// all nodes in the tree. *
//**********************************************************
template <class T>
void BinaryTree<T>::destroySubTree(TreeNode *nodePtr)
{
if (nodePtr)
{
if (nodePtr->left)
destroySubTree(nodePtr->left);
if (nodePtr->right)
destroySubTree(nodePtr->right);
delete nodePtr;
}
}
//**********************************************************
// searchNode determines if a value is present in the tree.*
// If so, the function returns true. Otherwise it returns *
// false.
//**********************************************************
template <class T>
bool BinaryTree<T>::searchNode(T item)
{
TreeNode *nodePtr = root;
while (nodePtr)
{
if (nodePtr->value == item)
return true;
else if (item < nodePtr->value)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
//*********************************************************
// remove calls deleteNode to delete the node whode value *
// member is the same as num *
//*********************************************************
template <class T>
void BinaryTree<T>::remove(T item)
{
deleteNode(item, root);
}
//*********************************************************
// deleteNode deletes the node whose value member is the *
// same as num *
//*********************************************************
template <class T>
void BinaryTree<T>::deleteNode(T item, TreeNode *&nodePtr)
{
if (item < nodePtr->value)
deleteNode(item, nodePtr->left);
else if (item > nodePtr->value)
deleteNode(item, nodePtr->right);
else
makeDeletion(nodePtr);
}
//*********************************************************
// makeDeletion takes a reference to apointer to the node *
// that is to be deleted. The node is removed and the *
// branches of the tree below the node are reattached *
//*********************************************************
template <class T>
void BinaryTree<T>::makeDeletion(TreeNode *&nodePtr)
{
// Define a temporary pointer to use in reattaching
// the left subtree
TreeNode *tempNodePtr;
if (nodePtr == NULL)
cout << "Cannot delete empty node.\n";
else if (nodePtr->right == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->left; // Reattach the left child
delete tempNodePtr;
}
else if (nodePtr->left == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // Reattach the right child
delete tempNodePtr;
}
}
//*********************************************************
// The displayInOrder function displays the values in the *
// subtree pointed to by nodePtr, via inorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayInOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
displayInOrder(nodePtr->left);
cout << nodePtr->value.getEmpID() << " "
<< nodePtr->value.getEmpName() << endl;
displayInOrder(nodePtr->right);
}
}
//*********************************************************
// The displayPreOrder function displays the values in the*
// subtree pointed to by nodePtr, via Preorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayPreOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
cout << nodePtr->value.getEmpID() << " "
<< nodePtr->value.getEmpName() << endl;
displayInOrder(nodePtr->left);
displayInOrder(nodePtr->right);
}
}
//*********************************************************
// displayPostOrder function displays the values in the *
// subtree pointed to by nodePtr, via Postorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayPostOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
displayInOrder(nodePtr->left);
displayInOrder(nodePtr->right);
cout << nodePtr->value.getEmpID() << " "
<< nodePtr->value.getEmpName() << endl;
}
}
#endif
EMPLOYEEINFO
#ifndef EMPLOYEEINFO_H
#define EMPLOYEEINFO_H
#include <string>
#include <iostream>
using namespace std;
// This class has two data members to hold the employee ID
// and the name of the employee.
class EmployeeInfo
{
private:
int empID; // To hold employee ID number
string empName; // To hold employee name
public:
// Default Constructor
EmployeeInfo();
// Constructor
EmployeeInfo(int, string);
// Mutators
void setEmpID(int);
void setEmpName(string);
// Accessors
int getEmpID();
string getEmpName();
// Overloaded operator. This works directly with
// the insert function of BinaryTree.h more specifically
// line 71. *For my knowledge*
bool operator < (const EmployeeInfo &e)
{
if (empID < e.empID)
return true;
return false;
}
// Overloaded operator for the search function
bool operator == (const EmployeeInfo &e)
{
if (empID == e.empID)
return true;
return false;
}
};
#endif
#include "EmployeeInfo.h"
//*********************************************************
// Default constructor intializes the data members *
//*********************************************************
EmployeeInfo::EmployeeInfo()
{
empName = "";
empID = 0;
}
//*********************************************************
// Constructor sets the data members *
//*********************************************************
EmployeeInfo::EmployeeInfo(int ID, string name)
{
empName = name;
empID = ID;
}
//*********************************************************
// setEmpID stores the employee ID number *
//*********************************************************
void EmployeeInfo::setEmpID(int ID)
{
empID = ID;
}
//*********************************************************
// setEmpName stores the full name of the employee *
//*********************************************************
void EmployeeInfo::setEmpName(string name)
{
empName = name;
}
//*********************************************************
// getEmpID returns the employee ID number *
//*********************************************************
int EmployeeInfo::getEmpID()
{
return empID;
}
//*********************************************************
// getEmpName returns the full name of the employee *
//*********************************************************
string EmployeeInfo::getEmpName()
{
return empName;
}
MAIN
#include "EmployeeInfo.h"
#include "BinaryTree.h"
#include <iostream>
using namespace std;
int main()
{
// Create an instance of BinaryTree
BinaryTree<EmployeeInfo> tree;
// Create an EmployeeInfo object
EmployeeInfo emp1(1021, "John Williams");
EmployeeInfo emp2(1057, "Bill Witherspoon");
EmployeeInfo emp3(2487, "Jennifer Twain");
EmployeeInfo emp4(3769, "Sophia Lancaster");
EmployeeInfo emp5(1017, "Debbie Reece");
EmployeeInfo emp6(1275, "George McMullen");
EmployeeInfo emp7(1899, "Ashley Smith");
EmployeeInfo emp8(4218, "Josh Plemmons");
tree.insertNode(emp1);
tree.insertNode(emp2);
tree.insertNode(emp3);
tree.insertNode(emp4);
tree.insertNode(emp5);
tree.insertNode(emp6);
tree.insertNode(emp7);
tree.insertNode(emp8);
// Search for an employee
char again = 'y'; // To hold yes
int id; // To hold ID number from user
cout << "Would you like to search for an employee?\n";
cout << "Enter Y for yes or N for No: ";
cin >> again;
if (again)
{
do
{
cout << "Enter the ID number of the employee: ";
cin >> id;
// Create an EmployeeInfo object to store the user's
// search parameters
EmployeeInfo info;
info.setEmpID(id);
// If search finds what the user entered display the
// corresponding employee
if (tree.searchNode(info))
{
cout << info.getEmpName() << endl; // Not right?
}
else
cout << "ID not found!" << endl;
cout << "Would you like to search for an employee?\n";
cout << "Enter Y for yes or N for No: ";
cin >> again;
}while (again == tolower('Y'));
}
// Display in order
tree.displayInOrder();
cout << endl;
tree.displayPreOrder();
cout << endl;
tree.displayPostOrder();
}
Ok I changed the code up to get the bool to work and the if (tree.searchNode(info)) but I don't think the cout statement is right. Can someone look at my searchNode function and how I called it in main and let me know what I'm doing wrong?
Problem lies here
info.setEmpID(1021);
info.setEmpID(1057);
info.setEmpID(2487);
info.setEmpID(3769);
info.setEmpID(1017);
info.setEmpID(1275);
info.setEmpID(1899);
info.setEmpID(4218);
info.setEmpName("John Williams");
info.setEmpName("Bill Witherspoon");
info.setEmpName("Jennifer Twain");
info.setEmpName("Sophia Lancaster");
info.setEmpName("Debbie Reece");
info.setEmpName("George McMullen");
info.setEmpName("Ashley Smith");
info.setEmpName("Josh Plemmons");
You are not adding anything to info but every time you call setEmpName() you are updating info object.
You can make few changes in searchNode method as below
template <class T>
bool BinaryTree::searchNode(T &item)
{
TreeNode *nodePtr = root;
while (nodePtr)
{
if (nodePtr->value == item)
{
item.setEmpName(nodePtr->value.getEmpName());
return true;
}
else if (item < nodePtr->value)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
In main() method
do
{
cout << "Enter the ID number of the employee: ";
cin >> id;
BinaryTree<EmployeeInfo> temp;
if ((temp=tree.searchNode(id))!=NULL)
{
cout << temp.getEmpName() << endl;
}
else{
cout<<"ID not found"<<endl;
}
cout << "Would you like to search for an employee?\n";
cout << "Enter Y for yes or N for No: ";
cin >> again;
}while (again == tolower('Y'));
//New changes...
Made change in declaration of searchNode(T) to searchNode(T &)...In your new code the name of employee found was not set in info thats why when you are trying to print EmpName there was not output...So the change is pass the reference of EmployeeInfo to searchitem(T &)
template
bool BinaryTree::searchNode(T &item)
{
TreeNode *nodePtr = root;
while (nodePtr)
{
if (nodePtr->value == item)
{
item.setEmpName(nodePtr->value.getEmpName());
return true;
}
else if (item < nodePtr->value)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
First create a class called EmployeeInfo that holds two private data members. One data member is an integer called empID which holds the id number of the employee. The second data member is a string called empName which holds the full name of the employee. The program will create an instance of the binary tree class with a data type of EmployeeInfo (BinaryTree). The binary tree will be sorted by the Employee ID number found in the EmployeeInfo class. The program should then allow the user to search for Employee by the Employee ID. If the employee is found in the tree, its name and ID should be displayed. If not, a message should be displayed indicating that it was not found.
I'm having a problem displaying the employee number and name. I get a long list of error codes that I can't figure out. Please point me in the right direction. Above is what I'm trying to accomplish.
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
using namespace std;
// This class is a template class that creates a binary
// tree that can hold values of any data type. It has
// functions to insert a node, delete a node, display the
// tree In Order, Pre Order and Post Order, search for a
// value, count the number of total nodes, left nodes,
// and a function to determine the height of the tree.
template <class T>
class BinaryTree
{
private:
struct TreeNode
{
T value; // The value in the node
TreeNode *left; // Pointer to left child node
TreeNode *right; // Pointer to right child node
};
TreeNode *root; // Pointer to the root node
// Private member functions
void insert(TreeNode *&, TreeNode *&);
void destroySubTree(TreeNode *);
void deleteNode(T, TreeNode *&);
void makeDeletion(TreeNode *&);
void displayInOrder(TreeNode *) const;
void displayPreOrder(TreeNode *) const;
void displayPostOrder(TreeNode *) const;
int counter(TreeNode *);
int leafCounter(TreeNode *);
int height(TreeNode *);
public:
// Constructor
BinaryTree()
{ root = NULL; }
// Destructor
~BinaryTree()
{ destroySubTree(root); }
// Binary tree operations
void insertNode(T);
bool searchNode(T);
void remove(T);
void displayPreOrder() const
{ displayPreOrder(root); }
void displayInOrder() const
{ displayInOrder(root); }
void displayPostOrder() const
{ displayPostOrder(root); }
// Node counter
int counter()
{
int n = counter(root);
return n;
}
// Leaf counter
int leafCounter()
{
int leaf = leafCounter(root);
return leaf;
}
// Height of the tree
int height()
{
int h = height(root);
return h;
}
};
//*********************************************************
// insert function accepts a TreeNode pointer and a *
// pointer to a node. The function inserts the node into *
// the tree pointer to by the TreeNode pointer. This *
// function is call recursively. *
//*********************************************************
template <class T>
void BinaryTree<T>::insert(TreeNode *&nodePtr, TreeNode *&newNode)
{
if (nodePtr == NULL)
nodePtr = newNode; // Insert the node
else if (newNode->value < nodePtr->value)
insert(nodePtr->left, newNode); // Search the left branch
else
insert(nodePtr->right, newNode);// Search the right branch
}
//*********************************************************
// insertNode creates anew node to hold num as its value *
// and passes it to the insert function. *
//*********************************************************
template <class T>
void BinaryTree<T>::insertNode(T item)
{
TreeNode *newNode; // Pointer to a new node
// Create anew node and store num in it
newNode = new TreeNode;
newNode->value = item;
newNode->left = newNode->right = NULL;
// Insert the node
insert(root, newNode);
}
//**********************************************************
// destroySubTree is called by the destructor. It deletes *
// all nodes in the tree. *
//**********************************************************
template <class T>
void BinaryTree<T>::destroySubTree(TreeNode *nodePtr)
{
if (nodePtr)
{
if (nodePtr->left)
destroySubTree(nodePtr->left);
if (nodePtr->right)
destroySubTree(nodePtr->right);
delete nodePtr;
}
}
//**********************************************************
// searchNode determines if a value is present in the tree.*
// If so, the function returns true. Otherwise it returns *
// false.
//**********************************************************
template <class T>
bool BinaryTree<T>::searchNode(T item)
{
TreeNode *nodePtr = root;
while (nodePtr)
{
if (nodePtr->value == item)
return true;
else if (item < nodePtr->value)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
//*********************************************************
// remove calls deleteNode to delete the node whode value *
// member is the same as num *
//*********************************************************
template <class T>
void BinaryTree<T>::remove(T item)
{
deleteNode(item, root);
}
//*********************************************************
// deleteNode deletes the node whose value member is the *
// same as num *
//*********************************************************
template <class T>
void BinaryTree<T>::deleteNode(T item, TreeNode *&nodePtr)
{
if (item < nodePtr->value)
deleteNode(item, nodePtr->left);
else if (item > nodePtr->value)
deleteNode(item, nodePtr->right);
else
makeDeletion(nodePtr);
}
//*********************************************************
// makeDeletion takes a reference to apointer to the node *
// that is to be deleted. The node is removed and the *
// branches of the tree below the node are reattached *
//*********************************************************
template <class T>
void BinaryTree<T>::makeDeletion(TreeNode *&nodePtr)
{
// Define a temporary pointer to use in reattaching
// the left subtree
TreeNode *tempNodePtr;
if (nodePtr == NULL)
cout << "Cannot delete empty node.\n";
else if (nodePtr->right == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->left; // Reattach the left child
delete tempNodePtr;
}
else if (nodePtr->left == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // Reattach the right child
delete tempNodePtr;
}
}
//*********************************************************
// The displayInOrder function displays the values in the *
// subtree pointed to by nodePtr, via inorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayInOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
displayInOrder(nodePtr->left);
cout << nodePtr->value.getEmpID() << " "
<< getEmpName() << endl;
displayInOrder(nodePtr->right);
}
}
//*********************************************************
// The displayPreOrder function displays the values in the*
// subtree pointed to by nodePtr, via Preorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayPreOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
cout << nodePtr->value << endl;
displayInOrder(nodePtr->left);
displayInOrder(nodePtr->right);
}
}
//*********************************************************
// displayPostOrder function displays the values in the *
// subtree pointed to by nodePtr, via Postorder traversal *
//*********************************************************
template <class T>
void BinaryTree<T>::displayPostOrder(TreeNode *nodePtr) const
{
if (nodePtr)
{
displayInOrder(nodePtr->left);
displayInOrder(nodePtr->right);
cout << nodePtr->value << endl;
}
}
//*********************************************************
// counter counts the number of nodes the tree has *
//*********************************************************
template <class T>
int BinaryTree<T>::counter(TreeNode *nodePtr)
{
if (nodePtr == NULL)
return 0;
else
return counter(nodePtr->left) +1+ counter(nodePtr->right);
}
//*********************************************************
// leafCounter counts the number of leaf nodes in the tree*
//*********************************************************
template <class T>
int BinaryTree<T>::leafCounter(TreeNode *nodePtr)
{
if (nodePtr == NULL)
return 0;
else if (nodePtr->left == NULL && nodePtr->right == NULL)
return 1;
else
return leafCounter(nodePtr->left) + leafCounter(nodePtr->right);
}
//*********************************************************
// height returns the height of the tree *
//*********************************************************
template <class T>
int BinaryTree<T>::height(TreeNode *nodePtr)
{
if(nodePtr == NULL)
return -1;
if (height(nodePtr->left) <= height(nodePtr->right))
return (height(nodePtr->right) +1);
else
return (height(nodePtr->left) +1);
}
#endif
My EMPLOYEE CLASS
#ifndef EMPLOYEEINFO_H
#define EMPLOYEEINFO_H
#include <string>
using namespace std;
// This class has two data members to hold the employee ID
// and the name of the employee.
class EmployeeInfo
{
private:
int empID; // To hold employee ID number
string empName; // To hold employee name
public:
// Default Constructor
EmployeeInfo();
// Constructor
EmployeeInfo(int, string);
// Mutators
void setEmpID(int);
void setEmpName(string);
// Accessors
int getEmpID();
string getEmpName();
bool operator < (const EmployeeInfo &e)
{
if (empID < e.empID)
return true;
if (empName < e.empName)
return true;
return false;
}
};
#endif
EDIT I overloaded the < operator and all the errors went away
#include "EmployeeInfo.h"
//*********************************************************
// Default constructor intializes the data members *
//*********************************************************
EmployeeInfo::EmployeeInfo()
{
empID = 0;
empName = "";
}
//*********************************************************
// Constructor sets the data members *
//*********************************************************
EmployeeInfo::EmployeeInfo(int ID, string name)
{
empID = ID;
empName = name;
}
//*********************************************************
// setEmpID stores the employee ID number *
//*********************************************************
void EmployeeInfo::setEmpID(int ID)
{
empID = ID;
}
//*********************************************************
// setEmpName stores the full name of the employee *
//*********************************************************
void EmployeeInfo::setEmpName(string name)
{
empName = name;
}
//*********************************************************
// getEmpID returns the employee ID number *
//*********************************************************
int EmployeeInfo::getEmpID()
{
return empID;
}
//*********************************************************
// getEmpName returns the full name of the employee *
//*********************************************************
string EmployeeInfo::getEmpName()
{
return empName;
}
MAIN
#include "EmployeeInfo.h"
#include "BinaryTree.h"
#include <iostream>
using namespace std;
int main()
{
// Create an instance of BinaryTree
BinaryTree<EmployeeInfo> tree;
// Create an EmployeeInfo object
EmployeeInfo info;
EmployeeInfo emp1(1021, "John Williams");
EmployeeInfo emp2(1057, "Bill Witherspoon");
// Store the information
info.setEmpID(1021);
info.setEmpID(1057);
info.setEmpName("John Williams");
info.setEmpName("Bill Witherspoon");
tree.insertNode(emp1);
tree.insertNode(emp2);
// Display in order
tree.displayInOrder();
}
You need to provide overloads of the < and > operators for your EmployeeInfo class, and maybe other operators as well. At present it doesn't know how to evaluate item < nodePtr->value etc.
I don't see anything in the assignment that requires EmployeeInfo to have a default constructor.
You don't really need your destroySubtree() method. Your destructor should just read:
delete root;
and TreeNode should have a destructor that reads:
delete left;
delete right;
You don't need to check these for zero either, delete already does that.