Find parent node function for binary tree - c++

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

Related

Stack Overflow when inserting a node in a Binary Search Tree

I am new to programming in C++ but I am trying to create a Binary Search Tree.
The program seems to compile fine but it gives me this error:
Unhandled exception at 0x009229B7 in Lab001_CS3.exe: 0xC00000FD: Stack
overflow (parameters: 0x00000001, 0x00AD2FBC).
when I try to run it. The error occurs on this line of code:
void insert(int value) {
...
}
I am not sure what I am doing wrong, and I have never gotten this error before.
Here is the code:
#include <iostream>
using namespace std;
//create a node struct
struct node {
//member variables
int key;
node* left;
node* right;
//default constructor
node() {
key = 0;
left = NULL;
right = NULL;
cout << "a new node is created" << endl;
}
//constructor so can create a node in one line
node(int k) {
key = k;
left = NULL;
right = NULL;
cout << "a new node is created" << endl;
}
};
class Tree {
public:
//root node
node root;
//default constructor
Tree() {
root.key = 0;
root.left = NULL;
root.right = NULL;
}
//constructor to create the root node
Tree(int data) {
//set the data to the key
//set the right and left pointers to null
root.key = data;
root.left = NULL;
root.right = NULL;
}
//print the root node
void printRootNode() {
cout << "Root Node - Key: " << root.key << endl;
}
//insert functions
void insert(int value) {
/* If the newNode's key is less than the root key, traverse left
*/
if (value < root.key) {
/* if the left node is NULL */
if (root.left == NULL) {
root.left = new node(value);
cout << "assigned left" << endl;
}
else {
/* if the left node is important */
insert(value);
cout << "recurse" << endl;
}
}
if (value > root.key) {
/* if the right node is NULL */
if (root.right == NULL) {
root.right = new node(value);
cout << "assigned right" << endl;
}
else {
/* if the right node is important */
insert(value);
cout << "recurse" << endl;
}
}
}
};
//print inorder
void inorder(node* rt) {
//base
if (rt == NULL) {
return;
}
inorder(rt->left);
cout << " " << rt->key << endl;
inorder(rt->right);
}
int main() {
//create a tree for a root node
Tree t(16);
t.printRootNode();
//create newNode
node n1(20);
node n2(31);
//insert the new nodes
t.insert(20);
t.insert(31);
//keep the window from closing
system("pause");
}
Thank you for any help.
In your insert()
if (value < root.key) {
/* if the left node is NULL */
if (root.left == NULL) {
root.left = new node(value);
cout << "assigned left" << endl;
}
else {
/* if the left node is important */
insert(value);
cout << "recurse" << endl;
}
}
let's take this go left snippet as example, if root.left != NULL the code will enter else block and recursively call insert(value) forever, which cause stack overflow, the correct operation is make current node move to root.left, and then call insert(value) recursively.
also you don't need node class at all, tree class can do all the things.
again, here is not a good place for help you debug, you need to learn how to do this yourself :-).

Write a program, which converts the expression a b + c d e + * * into an expression tree using stack.

description
I don't know how to do this task.... but i just created a tree and enter value..can anyone please help me to do this task...the Stack is also of node type and we have to push value of operators like ab+ so we will push a as node then b as node and when + will come we make a tree and a and b will be its leafs node.
.Code
#include<iostream>
using namespace std;
class Node{
public:
int data;
Node *left;
Node *right;
Node()
{
data = 0;
left = NULL;
right = NULL;
}
};
class Tree
{
Node *root;
void insert(int d, Node *node)
{
if (d < node->data)
{
if (node->left == NULL)
{
Node *leaf = new Node();
leaf->data = d;
node->left = leaf;
}
else
{
insert(d, node->left);
}
}
else
{
if (node->right == NULL)
{
Node *leaf = new Node();
leaf->data = d;
node->right = leaf;
}
else
{
insert(d, node->right);
}
}
}
void inOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
inOrderDisplay(subRoot->left);
cout << subRoot->data << " ";
inOrderDisplay(subRoot->right);
}
}
void postOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
postOrderDisplay(subRoot->left);
postOrderDisplay(subRoot->right);
cout << subRoot->data << " ";
}
}
void preOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
cout << subRoot->data << " ";
preOrderDisplay(subRoot->left);
preOrderDisplay(subRoot->right);
}
}
void deleteSubtree(Node *subRoot)
{
if (subRoot != NULL)
{
deleteSubtree(subRoot->left);
deleteSubtree(subRoot->right);
cout << "\ndeleting: " << subRoot->data;
delete subRoot;
subRoot = NULL;
}
}
public:
Tree()
{
root = NULL;
}
~Tree()
{
deleteAll();
}
void insert(int d)
{
if (root == NULL)
{
Node *leaf = new Node();
leaf->data = d;
root = leaf;
}
else
{
insert(d, root);
}
}
void inOrderDisplay()
{
inOrderDisplay(root);
}
void postOrderDisplay()
{
postOrderDisplay(root);
}
void preOrderDisplay()
{
preOrderDisplay(root);
}
void deleteAll()
{
deleteSubtree(root);
}
};
.Main Class:
#include<iostream>
#include"task1.h"
using namespace std;
void main()
{
Tree tree;
tree.insert(10);
tree.insert(6);
tree.insert(14);
tree.insert(5);
tree.insert(8);
tree.insert(11);
tree.insert(18);
cout << endl;
system("pause");
//tree.deleteAll();
}
Based on the code you have here, you only have a void insert(int d, Node *node) function, no void insert(operator o, Node *node) function.
I think this shows that you missed an important point here. Every node in the tree can either be an integer (as you did) or an operator. In both cases, I'd call it a string. Every node that is not a leaf must be an operator, and all leafs must be integers (or strings that represents operators/integer in our case).
Then, iterating over your input, the first three item should result in something like:
+
/ \
a b
The next step would be to build more sub trees (not sure of the definition of the input you have), keep them in your stack and then construct more inner nodes of the tree.
So if the tree I showed above is called Tree(+) (for ease of use), and the initial stack was [a,b,+,c,d,e,*,*], then after one iteration you'll have [Tree(+),c,d,e,*,*] and you continue from there.

Binary tree class implematation

I have the following code. It creates a binary tree class. The functions are insert(), pre_order(), post_order(), in_order(). But when I debug it I get zeros values. Also I insert 9 values but only have 7 zeros. Why I did wrong?
#include <iostream>
using namespace std;
//Begin the construction of the BINARY TREE
struct tree_node {
tree_node *left;
tree_node *right;
int data;
};
//Declaring the class
class bst {
tree_node *root; //creating the root of the binary tree
public:
bst() {
root = NULL; //intialize the default construction, set the root to NULL
}
int is_empty() { //check for empty graph
return (root == NULL);
}
//Manipulating the Binary Tree
void insert(int item);
void remove_it(int value); //difficult implementation
//Graph Traversal of Binary Tree
void in_order_trav();
void in_order(tree_node *);
void pre_order_trav();
void pre_order(tree_node *);
void post_order_trav();
void post_order(tree_node *);
};
void bst::insert(int item) {
tree_node *p = new tree_node;
tree_node *parent;
p->left = NULL;
p->right = NULL;
parent = NULL;
if (is_empty()) {
root = p;
}
else {
tree_node *ptr;
ptr = root;
while (ptr != NULL) {
parent = ptr;
if (item > ptr->data)
ptr = ptr->right;
else
ptr = ptr->left;
}
if (item < parent->data)
parent->left = p;
else
parent->right = p;
}
}
/*************In Order Traversal*****************************/
// Begin
void bst::in_order_trav() {
in_order(root);
}
void bst::in_order(tree_node *ptr) {
if (ptr!=NULL) {
in_order(ptr->left);
cout << " " << ptr->data << " ";
in_order(ptr->right);
}
}
// End
/***********************************************************/
/*************Pre Order Traversal*****************************/
// Begin
void bst::pre_order_trav() {
pre_order(root);
}
void bst::pre_order(tree_node *ptr) {
if (ptr!=NULL) {
cout << " " << ptr->data << " ";
pre_order(ptr->left);
pre_order(ptr->right);
}
}
// End
/***********************************************************/
/*************Post Order Traversal*****************************/
// Begin
void bst::post_order_trav() {
post_order(root);
}
void bst::post_order(tree_node *ptr) {
if(ptr!=NULL) {
post_order(ptr->left);
post_order(ptr->right);
cout << " " << ptr->data << " ";
}
}
// End
/***********************************************************/
int main() {
bst bin_tree; //create the Binary Tree
bin_tree.insert(20);
bin_tree.insert(30);
bin_tree.insert(52);
bin_tree.insert(254);
bin_tree.insert(2);
bin_tree.insert(24);
bin_tree.insert(25);
bin_tree.insert(42);
bin_tree.insert(59);
bin_tree.in_order_trav(); //in order traversal
bin_tree.pre_order_trav(); //pre order traversal
bin_tree.post_order_trav(); //post order traversal
}
The node value should be initialized(p->data = item) at function insert() as below
void bst::insert(int item) {
tree_node *p = new tree_node;
tree_node *parent;
p->left = NULL;
p->right = NULL;
p->data = item;
parent = NULL;
... ...
}
Ok the solution is silly! -.-
I forgot to add that line in insert routine!
p->data = item;

BinaryTree Template Crashes

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.

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