Binary Search Tree Template - c++

I'm fairly new to c++ and I've recently received a project to create my own Binary Search Tree using a Template. The goal is for the Binary Tree to be able to take in any kind of data type. IntBinaryTree.h should be able to take in object of EmployeeInfo. I've gotten it to compile but I get an error message of glibc detected double free or corruption (fasttop) I'm not exactly sure what this means. Also I'm not sure if I've set the program up correctly. Also note, I'm testing functions 1 by 1 in main.cpp that's why there is only insert function being used.
Update I allocated memory for the insertNode function by TreeNode *newNode = new TreeNode, now I get error message of "in instantiation of void IntBinaryTree::insertNode(T) [with T = EmployeeInfo]: main.cpp:22:29 required from here "
#ifndef EMPLOYEEINFO_H
#define EMPLOYEEINFO_H
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
class EmployeeInfo
{
public:
EmployeeInfo(int, string);
~EmployeeInfo();
//void print();
int getEmployeeID();
string getEmployeeName();
void setEmployeeID(int);
void setEmployeeName(string);
bool operator ==(const EmployeeInfo &eO1) {return EmployeeID == eO1.EmployeeID;}
bool operator >(const EmployeeInfo &eO1) {return EmployeeID > eO1.EmployeeID;}
bool operator <(const EmployeeInfo &eO1) {return EmployeeID < eO1.EmployeeID;}
private:
int EmployeeID;
string EmployeeName;
};
#endif
#include"EmployeeInfo.h"
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
EmployeeInfo::EmployeeInfo(int empID, string name)
{
EmployeeID = empID;
EmployeeName = name;
}
EmployeeInfo::~EmployeeInfo()
{
}
int EmployeeInfo::getEmployeeID()
{
return EmployeeID;
}
string EmployeeInfo::getEmployeeName()
{
return EmployeeName;
}
void EmployeeInfo::setEmployeeID(int empID)
{
EmployeeID = empID;
}
void EmployeeInfo::setEmployeeName(string name)
{
EmployeeName = name;
}
#ifndef INTBINARYTREE_H
#define INTBINARYTREE_H
#include <iostream>
#include<string>
#include<cstdlib>
#include <iomanip>
using namespace std;
template<class T>
struct TreeNode
{
T value;
TreeNode<T> *left;
TreeNode<T> *right;
};
template<class T>
class IntBinaryTree
{
private:
TreeNode<T>* root;
void insert(TreeNode<T> *&, TreeNode<T> *&);
void destroySubTree(TreeNode<T> *);
void deleteNode(T, TreeNode<T> *&);
void makeDeletion(TreeNode<T> *&);
void displayInOrder(TreeNode<T> *) const;
void displayPreOrder(TreeNode<T> *) const;
void displayPostOrder(TreeNode<T> *) const;
public:
//Constructor
IntBinaryTree();
~IntBinaryTree(){destroySubTree(root);}
//Binary Tree Operations
void insertNode(T);
bool searchNode(T);
void remove(T);
void displayInOrder() const{ displayInOrder(root);}
void displayPreOrder() const{ displayPreOrder(root);}
void displayPostOrder() const{ displayPostOrder(root);}
};
template<class T>
IntBinaryTree<T>::IntBinaryTree()
{
root = NULL;
}
template<class T>
void IntBinaryTree<T>::insert(TreeNode<T> *&nodePtr, TreeNode<T> *&newNode)
{
if (nodePtr == NULL)
nodePtr = newNode;
else if (newNode->value < nodePtr->value)
insert(nodePtr->left, newNode);
else
insert(nodePtr->right, newNode);
}
template<class T>
void IntBinaryTree<T>::insertNode(T val)
{
TreeNode<T> *newNode;
newNode->value = val;
newNode->left = newNode->right = NULL;
//Insert the Node
insert(root, newNode);
}
template<class T>
void IntBinaryTree<T>::displayInOrder(TreeNode<T> *nodePtr) const
{
if(nodePtr){
displayInOrder(nodePtr->left);
cout << nodePtr->value << " ";
displayInOrder(nodePtr->right);
}
}
template<class T>
void IntBinaryTree<T>::displayPreOrder(TreeNode<T> *nodePtr) const
{
if(nodePtr){
cout << nodePtr->value << " ";
displayPreOrder(nodePtr->left);
displayPreOrder(nodePtr->right);
}
}
template<class T>
void IntBinaryTree<T>::displayPostOrder(TreeNode<T> *nodePtr) const{
if(nodePtr){
displayPostOrder(nodePtr->left);
displayPostOrder(nodePtr->right);
cout << nodePtr->value << " ";
}
}
template<class T>
void IntBinaryTree<T>::destroySubTree(TreeNode<T> *nodePtr){
if(nodePtr != NULL)
{
if(nodePtr->left != NULL)
{
destroySubTree(nodePtr->left);
}
if(nodePtr->right != NULL)
{
destroySubTree(nodePtr->right);
}
delete nodePtr;
}
cout << "Binary Tree Destroyed\n";
}
template<class T>
bool IntBinaryTree<T>::searchNode(T val){
TreeNode<T>* nodePtr = root;
while(nodePtr){
if (nodePtr->value == val)
return true;
else if (val < nodePtr->value)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
template<class T>
void IntBinaryTree<T>::remove(T val){
deleteNode(val, root);
}
template<class T>
void IntBinaryTree<T>::deleteNode(T val, TreeNode<T> *&nodePtr){
if (val < nodePtr->value)
deleteNode(val, nodePtr->left);
else if (val > nodePtr->value)
deleteNode(val, nodePtr->right);
else
makeDeletion(nodePtr);
}
template<class T>
void IntBinaryTree<T>::makeDeletion(TreeNode<T> *&nodePtr){
TreeNode<T> *tempNodePtr;
if (nodePtr == NULL)
cout << "Cannot delete empty node\n";
else if(nodePtr->right == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->left;
delete tempNodePtr;
}
else if(nodePtr->left == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->right;
delete tempNodePtr;
}
//If the node has two Children
else
{
//Move one node to 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;
}
}
#endif
#include"EmployeeInfo.cpp"
#include"IntBinaryTree.h"
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int main()
{
IntBinaryTree<EmployeeInfo> mytree;
EmployeeInfo employee1(1021, "John Williams");
EmployeeInfo employee2(1057, "Bill Witherspoon");
EmployeeInfo employee3(2487, "Jennifer Twain");
EmployeeInfo employee4(3769, "Sophia Lancaster");
EmployeeInfo employee5(1017, "Debbie Reece");
EmployeeInfo employee6(1275, "George McMullen");
EmployeeInfo employee7(1899, "Ashley Smith");
EmployeeInfo employee8(4218, "Josh Plemmons");
mytree.insertNode(employee1);
mytree.insertNode(employee2);
mytree.insertNode(employee3);
mytree.insertNode(employee4);
mytree.insertNode(employee5);
mytree.insertNode(employee6);
mytree.insertNode(employee7);
mytree.insertNode(employee8);
return 0;
}

In your insertNode method, you do not allocate any space for your node and you use an uninitialized pointer:
TreeNode<T> *newNode;
newNode->value = val;
newNode->left = newNode->right = NULL;
You need to allocate some memory for your node:
TreeNode<T> *newNode = new TreeNode<T>;
I highly recommend learning to use the debugger, so you can trace through your code line by line to see what it is doing. No one writes perfect code each time, and a debugger is the easiest way to see what is going wrong.
Edit:
The above won't work as you don't have a default constructor for Employee, but you only have a default constructor for TreeNode. This means you can't create a TreeNode that contains an Employee.
The best way to fix this, is to add a constructor to TreeNode that takes a parameter that is a reference to a T object, so that it can initialize its own value object from that parameter.
Add this to your TreeNode class
TreeNode(T &val) : value(val), left(NULL), right(NULL) { }
This code copies the val parameter into value and initializes the left and right pointers.
Then change your insert code to.
TreeNode<T> *newNode = new TreeNode < T > (val) ;
//Insert the Node
insert(root, newNode);
Note that there is no need to set the left and right pointers, as the constructor now does that for you.

Related

My implementation of the binary search tree is not working because I keep getting error that my node and typedef item is not defined

The important part is the header file for some reason when I include it to the implementation file it does not include the struct node I made or the typedef did I do anything wrong? I have never had this problem before and have done it numerous times. Do you guys have any suggestions? this is the error I am getting Node was not declared in this scope and item does not name a type.
//Header File
#include <iostream>
#include <fstream>
#include <cstring>
#include <iomanip>
#include <string>
#ifndef BST
using namespace std;
class BST
{
public:
typedef int item;
//constructors
BST() {root =NULL;}
// Destructor
~BST();
//Modification member functions
void reinitialize();
void insert( const item& entry);
void remove( const item& target);
// constant member functions
bool empty() const{return root == NULL;}
int length();
bool present(const item& target);
// definitions
private:
struct Node//my structure
{
item data;
Node *left;
Node *right;
};
Node *root;
//recursive functions
void print(Node *p);
void destroy(Node *r);
void help_insert(Node *&t, const item& entry);
void help_remove(Node *&t, const item& entry);
void remove_node(Node *&t);
};
#define BST
#endif
Source file
//Implementation of the Binary search tree
//Kyle Ripplinger
#include <cassert>
#include <iostream>
#include <iomanip>
#include "BST.h"
using namespace std;
/*BST::~BST()
{
destroy(root);
}
void BST::destroy(Node *r)//doesn't work here
{
if(r!= NULL)
{
destroy(r->left);
destroy(r->right);
delete r;
}
}
int BST::length()
{
return find_length(root);// doesnt work
}
int BST::find_length(Node *r)
{
if (r== NULL)
return 0;
else
return find_length(r->left)+1+find_length(r->right);
}*/
void BST:: insert(const item& entry)
{
help_insert(root, entry);
}
void BST:: help_insert(Node *&t,const item& entry)
{
if(t == NULL)
{
t = new Node;
t -> data = entry;
t -> left = NULL;
t -> right = NULL;
}
else if(entry <t->data)
help_insert(t->left,entry);
else
help_insert(t->right,entry);
}
void BST:: remove(const item& target)
{
assert(present(target));
help_remove(root,target);
}
void BST:: help_remove(Node *&t, const item& target)
{
if {t->data = target)
remove_node(t);
else if(target < t->data)
help_remove(t->left, target);
else
help_remove(t->right, target);
}
void BST:: remove_node(Node *&t)
{
Node *ptr;
Node *back;
if(t->left == NULL && t->right == NULL)//leaf
{
delete t;
t = NULL;
}
else if(t->left == NULL)//has right child only
{
ptr = t;
t = t->right;
delete ptr;
}
else if(t ->right == NULL)//has left child only
{
ptr = t;
t = t->left;
delete ptr;
}
else//has both children on tree find the leftmost node in the right subtree
{
back = t;
ptr = t->right;
while(ptr->left != NULL)
{
back = ptr;
ptr = ptr->left;
}
t->data = ptr->data;
if(back == t)
remove_node(back->right);
else
remove_node(back->left);
}
}
bool BST::present(Item target)
{
Node *p;
p = root;
while(true)
{
if(p == NULL)
return false;
else if (target < p-> data)
p = p->left;
else if(target == p->data)
return true;
else
p= p-> right;
}
}
/*void BST::print(Node *p)
{
if(p!=NULL)
{
print(p->left);
cout << p-> data << endl;
print(p->right);
}
}*/
The compiler is correct. Because of your include guard, your definition of
void BST::insert(const item& entry)
became
void ::insert(const item& entry)
and there is no type called item in the global context.
Debugging tip: to try to point the compiler in the right direction, I changed that first line of your declaration to
void BST::insert(const BST::item& entry)
When the compiler reported "error: 'item' in namespace '::' does not name a type", it was rather clear that the BST was disappearing somehow.

Find level of binary tree with randomly generated numbers inserted c++

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;
}

c++ virtual functions with Linked List

I'm running into some problems while trying to use a virtual function within my classes.
I'm using a Linked List to store Employee, Staff and Managers - which inherit each other (Staff and Managers inherit Employee base class).
I need to be able to access a function called getType which returns either "Staff Member" or "Manager" based on which class it is.
this snipit of code is my creation of staff and managers.
Staff staff4 = { "Lisa", "22/02/2012", 0004, HR, 8.9, 34.50 };
Employee* pStaff4 = &staff4;
Employee& testStaff4 = staff4;
myList->addInFront(testStaff4);
Staff staff5 = { "Jade", "23/03/2014", 0003, HR, 6.4, 38.50 };
Employee* pStaff5 = &staff5;
Employee& testStaff5 = staff5;
myList->addInFront(testStaff5);
Manager manager1 = { "Lily", "01/09/2012", 0001, MARKETING, 75968 };
Employee* pMan1 = &manager1;
Employee& testMan1 = manager1;
myList->addInFront(testMan1);
Manager manager2 = { "Craig", "27/03/2011", 0002, HR, 82478 };
Employee* pMan2 = &manager2;
Employee& testMan2 = manager2;
myList->addInFront(testMan2);
//cout << pStaff5->getType();
//system("pause");
This is my employee.h (i've taken out other functions to save space on this post)
class Employee
{
protected:
string name;
string startDate;
unsigned long empNumber;
string dept;
public:
Employee() {};
Employee(string, string, unsigned long, string);
virtual const string getType()
{
return "Emp";
}
};
class Manager : public Employee
{
private:
unsigned long salary;
public:
virtual const string getType()
{
return "Manager";
}
};
class Staff : public Employee
{
private:
float hourlyRate;
float hoursPerWeek;
public:
const string getType()
{
return "Staff Member";
}
};
and finally this is how i'm attempting to call the getType() function:
void displayList(const List& list)
{
List temp(list);
while (!temp.isEmpty())
{
cout << temp.first()->item.getType() << "\n";
cout << temp.first()->item.getName() << "\n";
temp.deleteFirst();
}
}
Here is my list header and .cpp
list.h
//#include <string>
#include "Employees.h"
#define Item Employee
using namespace std;
struct Node
{
Item item;
Node* next;
};
class List
{
private:
Node* head;
Node* end() const;
void copy(const List&);
void destroy();
public:
List();
List(const List&);
~List();
List& operator=(const List&);
bool operator==(const List&);
bool isEmpty() const;
Node* first() ;
Item last() const;
List tail() const;
void addInFront(const Item&);
void addAtEnd(const Item&);
void deleteFirst();
Node* search(const long);
bool searchDelete(const long);
};
list.cpp
#include "stdafx.h"
#include "List.h"
#include <assert.h>
List::List()
{
head = NULL;
}
List::List(const List& otherList) : head(nullptr)
{
copy(otherList);
}
bool List::isEmpty() const
{
return (head == nullptr);
}
Node* List::first()
{
assert(head != nullptr);
return head;
}
void List::deleteFirst()
{
if (head != NULL)
{
Node* tmp = head->next;
delete head;
head = tmp;
}
}
void List::addInFront(const Item& data)
{
Node* nodePtr = new Node;
assert(nodePtr != nullptr);
nodePtr -> item = data;
nodePtr ->next = head;
head = nodePtr;
}
Node* List::search(const long longID)
{
}
bool List::searchDelete(const long longID)
{
Node *temp, *prevNode;
temp = head;
prevNode = NULL;
while (temp != NULL)
{
}
}
Node* List::end() const
{
if (head == nullptr)
return nullptr;
else
{
Node* nodePtr = head;
while (nodePtr->next != nullptr)
{
nodePtr = nodePtr->next;
}
return nodePtr;
}
}
void List::addAtEnd(const Item& data)
{
Node* nodePtr = new Node;
assert(nodePtr != nullptr);
if (head == nullptr)
{
head = nodePtr;
nodePtr->item = data;
}
else
{
nodePtr->item = data;
Node* ptr = end();
ptr->next = nodePtr;
}
}
List& List::operator=(const List& rhs)
{
if (&rhs != this)
{
destroy();
copy(rhs);
}
return *this;
}
void List::copy(const List& otherList)
{
}
void List::destroy()
{
while (head != nullptr)
{
Node* ptr = head;
head = head->next;
delete ptr;
}
}
List::~List()
{
}
apologies about the length of these files.
I'm confused as to why it won't call the appropriate virtual function, as you can see in the first code snipit that i used pStaff5->getType() and that worked - however I can't access the nodes like that once i've stored them in a linked list...(can I?)
Kind regards
Craig
Your list nodes store an Item but that is only the base class. When you try to put a Manager or Staff in the list only the base class part of the object is copied into the list (this is called "slicing") and not the derived parts of the object.
When you call the virtual function you only get the base class overrider for the virtual, because the object stored in the list is only an Employee.
(You should consider making Node and List into templates, instead of doing #define Item Employee)

BinaryTree search function

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;
}

BinaryTree Employee Class

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.