I am creating a binary tree and want to just Search function but I want to know how many nodes are visited to find a value. in the search function.
Here is the hearder file
#ifndef INTBINARYTREE_H
#define INTBINARYTREE_H
class IntBinaryTree
{
private:
struct TreeNode
{
int value; // The value in node .
TreeNode *left; //pointer to left node
TreeNode *right; // Pointer to right child node
};
TreeNode *root;
//private member functions
void insert(TreeNode *&,TreeNode *&);
void displayInOrder(TreeNode *) const;
void displayPreOrder(TreeNode *) const;
void displayPostOrder(TreeNode *) const;
public:
IntBinaryTree()
{
root = nullptr;
}
// Binary search tree
int searchNode(int);
void insertNode(int);
void displayInOrder() const
{
displayInOrder(root);
}
#endif // INTBINARYTREE_H
And here is the .cpp File I want to know how to for the search function if a value is not found zero and if value is found how many nodes are visited ?
#include "IntBinaryTree.h"
void IntBinaryTree::insert(TreeNode *&nodePtr, TreeNode *&newNode)
{
if (nodePtr == nullptr)
nodePtr=newNode; // insert the node
else if (newNode->value < nodePtr->value) `//search the left branch`
insert(nodePtr->left, newNode);
else
insert(nodePtr->right, newNode); //search the right branch
}
void IntBinaryTree::insertNode(int num)
{
TreeNode *newNode= nullptr; // pointer to a new node
//create a new node and store num in it
newNode = new TreeNode;
newNode->value= num;
newNode->left = newNode->right = nullptr;
//insert the node
insert(root, newNode);
}
int IntBinaryTree::searchNode(int num)
{
TreeNode *nodePtr = root;
while(nodePtr)
{
if (nodePtr->value==num)
{
cout<<"Node found"<<num<<endl;
}
else if (num < nodePtr->value)
nodePtr = nodePtr->left; // look to the left side of the branch if less than the value of the node
else
nodePtr = nodePtr->right; // look to the right side of the if not less than the value .
}
return 0;
}
Here is the Mainfile
#include <iostream>
#include "IntBinaryTree.h"
using namespace std;
int main()
{
IntBinaryTree tree;
cout << "inserting nodes" << endl;
tree.insertNode(5);
tree.insertNode(8);
tree.insertNode(3);
tree.insertNode(12);
tree.insertNode(9);
cout << "Done.\n";
tree.searchNode(5);
return 0;}
Can you please code it for me and edit and explain it briefly how does it work ?
Your includes are wrong.
There is a #include "IntBinaryTree.cpp" in your main.cpp. Because of this the insert member (and many others) exist twice. General rule: Never include cpp files.
Just remove the line, and you should be fine.
Related
I have been trying to get this function working for the longest time now. It is part of an assignment for an online course, but it seems no matter what I submit, the function fails for both the empty child test and the left child test. See code below. The main() function is deliberately commented out. Any info./input is much appreciated.
// C++ binary trees and stuff;
//
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
using namespace std;
class BST
{
public:
int data;
BST *left;
BST *right;
//BST *root;
// BST() constructor
BST (int num)
{
data = num;
left = nullptr;
right = nullptr;
root = nullptr;
}
// constructors for root node(s), initializing as root when no values exist yet;
BST() : root (nullptr){}
BST (BST *rootNode) : root(rootNode){}
void insert (int value)
{
BST *newNode = new BST();
newNode = root;
if (root == nullptr)
{
root = new BST (value);
}
else
{
root->data = value;
}
// check if newNode's value equals the passed-in value:
if (value == root->data)
{
//cout << "\nWarning! Value already exists in tree, so nothing will be done.\n";
return;
}
// check if value is < or > newNode's value:
if (value <= root->data)
{
if (root->left == nullptr)
{
// make a new node as the left child of this node,
root->left = new BST(value);
}
else
{
// recursively call insert() on tree's left side,
root->left->insert(value);
}
}
else
{
if (root->right == nullptr)
{
// make a new node as the right child of this node,
root->right = new BST(value);
}
else
{
// recursively call insert() on tree's right side,
root->right->insert(value);
}
}
}
public:
BST *root;
};
/*
int main (int argc, char *argv[])
{
//...insert code here,
// create nodes,...
BST rootNode(5);
BST leftNode(4);
BST rightNode(6);
// connect the nodes to the tree via rootNode.left and rootNode.right,..
rootNode.left = &leftNode;
rootNode.right = &rightNode;
printf ("\nData (root) value = %i, rootNode.left = %i, and rootNode.right = %i\n",
rootNode.data, rootNode.left->data, rootNode.right->data);
cout << "\n\nHello, Solar System!\n";
return 0;
}
*/
Okay, here's my suggestion. You need to reformat your code. You need two classes. You need a BST, and you need a Node. The various methods to add/remove/traverse are part of the BST class. Nodes are just Nodes.
So:
class BST_Node {
public:
int value;
BST_Node * left = nullptr;
BST_Node * right = nullptr;
// Define constructors, etc.
};
class BST {
public:
BST_Node * root = nullptr;
BST_Node * insert(int value);
void insertNode(BST_Node *node);
void insertNodeBelow(BST_Node *nodeToInsert, BST_Node *startingNode);
};
BST_Node * BST::insert(int value) {
BST_Node * node = new BST_Node(value);
insertNode(node);
return node;
}
void BST::insertNode(BST_Node *node) {
if (node == nullptr) {
return;
}
if (root == nullptr) {
root = node;
}
else {
insertNodeBelow(node, root);
}
}
void BST::insertNodeBelow(BST_Node *node, BST_Node *startingNode) {
if (node == nullptr || startingNode == nullptr) {
return;
}
if (node->value < startingNode->value) {
if (startingNode->left != nullptr) {
insertNodeBelow(node, startingNode->left);
}
else {
startingNode->left = node;
}
}
else {
if (startingNode->right != nullptr) {
insertNodeBelow(node, startingNode->right);
}
else {
startingNode->right = node;
}
}
}
How this works... First, the logic of how to store nodes is in BST. Nodes don't care. Second, I made methods for either inserting a value or a node. Because I think that's handy. That should be fairly easy to understand.
The root node can be null, if so, then your inserted node is now root. Otherwise it calls the recursive insertion function. Now, you could simplify this a little, but I didn't want to get too clever.
So it's simple. We look to see where it belongs relative to the point we're at (initially the root). Either we go into the left branch or the right branch. But that branch could be empty, so you just plop it right in. If it's not empty, then you recurse.
I didn't test it.
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;
}
I'm attempting to build a binary search tree and then do a horizontal inorder print with the left most node as the first node displayed. Also, preceding each node is its depth (distance from root) as well as a tilde to help visualize the tree itself. Conceptually my code seems to be correct, but for whatever reason I can't seem to get it to build the tree properly. I figure that the error is most likely in my insert function, but I can't seem to locate it.
Any suggestions or ideas would be extremely helpful!
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <algorithm>
using namespace std;
typedef struct treeNode {
treeNode *leftChild;
treeNode *rightChild;
int data;
} treeNode;
void printTree(treeNode*);
int getNodeDepth(treeNode*);
treeNode* insert(treeNode*, int);
treeNode* createNewNode(int);
int main()
{
//read in file here
treeNode *root = NULL;
root = insert(root, 8);
root = insert(root, 1);
root = insert(root, 90);
root = insert(root, 3);
root = insert(root, 80);
root = insert(root, 6);
root = insert(root, 83);
printTree(root);
return 0;
}
/*
Purpose: Constructs a new node for the tree.
Inputs: The data for the node.
Outputs: returns the new node
*/
treeNode* createNewNode(int data)
{
treeNode *newNode = new treeNode;
newNode->data = data;
newNode->leftChild = NULL;
newNode->rightChild = NULL;
return newNode;
}
/*
Purpose: Calculates the depth of a given node using recursion.
Inputs: The node to check the depth on.
Outputs: returns the depth
*/
int getNodeDepth(treeNode *node)
{
if (node == NULL) // tree doesn't exist
return(0);
return(1 + max(getNodeDepth(node->leftChild), getNodeDepth(node->rightChild)));
}
/*
Purpose: Inserts a node into the tree.
Inputs: The node to be inserted and the data for the node.
Outputs: returns the inserted node
*/
treeNode* insert(treeNode *node, int data)
{
if (node == NULL)
return createNewNode(data);
else
{
if (data <= node->data)
{
node->leftChild = insert(node->leftChild, data);
}
else
{
node->rightChild = insert(node->rightChild, data);
}
return node;
}
}
/*
Purpose: Prints the BST in a horizontal inorder format.
Inputs: The root node.
Outputs: nothing
*/
void printTree(treeNode *node)
{
if (node == NULL)
return;
printTree(node->leftChild);
cout << "(" << (getNodeDepth(node)-1) << ") ";
for (int i=0; i<(getNodeDepth(node)-1); i++)
cout << "~";
cout << node->data << endl;
printTree(node->rightChild);
}
The current output is as follows:
(2) ~~1
(1) ~3
(0) 6
(3) ~~~8
(1) ~80
(0) 83
(2) ~~90
Obviously it can't have two roots (ie 6 and 83). Thanks!
For those in the future who wish for a correct implementation of the answer to my original question here is the refactored code that I came up. I decided to take an OOP approach and modified the insert and getNodeDepth function to appropriately work.
//
// Binary Search Tree
//
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <algorithm>
using namespace std;
// binary search tree
class BST {
private:
typedef struct treeNode {
treeNode *leftChild;
treeNode *rightChild;
int data;
} treeNode;
treeNode *root;
public:
//Constructor
BST() { root = NULL; }
/*
Purpose: Constructs a new node for the tree.
Inputs: The data for the node.
Outputs: returns the new node
*/
treeNode* createNewNode(int data)
{
treeNode *newNode = new treeNode;
newNode->data = data;
newNode->leftChild = NULL;
newNode->rightChild = NULL;
return newNode;
}
//Check if the tree is empty
bool isEmpty() const { return root==NULL; }
/*
Purpose: Calculates the depth of a given node using recursion.
Inputs: The node to check the depth on and the node to check the depth from.
Outputs: returns the depth
*/
int getNodeDepth(treeNode *node, treeNode *from)
{
if (node == from)
return 0;
else if (node->data < from->data)
return getNodeDepth(node, from->leftChild) + 1;
else
return getNodeDepth(node, from->rightChild) + 1;
}
/*
Purpose: Inserts a node into the tree.
Inputs: The data for the node.
Outputs: none
*/
void insert(int newData)
{
treeNode* t = createNewNode(newData);
treeNode* parent;
parent = NULL;
if(isEmpty()) //check if tree exists or not
root = t;
else {
//Note: ALL insertions are as leaf nodes
treeNode* curr;
curr = root;
// Find the Node's parent
while(curr)
{
parent = curr;
if (t->data > curr->data)
curr = curr->rightChild;
else
curr = curr->leftChild;
}
if ((t->data) < (parent->data))
parent->leftChild = t;
else
parent->rightChild = t;
}
}
/*
Purpose: Prints the BST in a horizontal inorder format.
Inputs: The root node.
Outputs: nothing
*/
void printTree(treeNode *node)
{
if (node == NULL)
return;
printTree(node->leftChild);
cout << "(" << getNodeDepth(node, root) << ") ";
for (int i=0; i<getNodeDepth(node, root); i++)
cout << "~";
cout << node->data << endl;
printTree(node->rightChild);
}
//Getter for private member variable root
void printInorder()
{
printTree(root);
}
};
int main()
{
// read file in here
BST temp;
temp.insert(8);
temp.insert(1);
temp.insert(90);
temp.insert(3);
temp.insert(80);
temp.insert(6);
temp.insert(83);
temp.printInorder();
return 0;
}
The correct output looks as follows with 8 as the root:
(1) ~1
(2) ~~3
(3) ~~~6
(0) 8
(2) ~~80
(3) ~~~83
(1) ~90
Hope this helps!
In the first you shouldn't write treeNode twice
typedef struct {
treeNode *leftChild;
treeNode *rightChild;
int data;
} treeNode;
In the second you create a memory leak:
treeNode *root = new treeNode;
root = NULL;
You should write:
treeNode *root = NULL;
Obviously it can't have two roots (ie 6 and 83). Thanks!
6 and 83 aren't roots. 8 is a root. So your program gave right answer.
I am writing a binary tree (for only numbers zero or larger) in C++ and for some reason all the values but the head seem to be zero (when I add an element) and I am not sure why that is happening. This seems like it would be rather obvious but I've been staring at this for 2 hours and can't seem to figure out what is happening.
Here is my BinaryTree.cpp:
#include "BinaryTree.h"
BinaryTree::Node::Node(){
lChild = NULL;
rChild = NULL;
data = -1;
}
BinaryTree::Node::Node(int data){
lChild = NULL;
rChild = NULL;
data = data;
}
BinaryTree::BinaryTree(){
head = new Node();
}
BinaryTree::BinaryTree(int num){
head = new Node(num);
}
void BinaryTree::addElement(int data){
addElement(data, head);
}
void BinaryTree::addElement(int data, Node * node){
if( node -> data != -1){
if(node -> data > data){
if(node -> lChild){
addElement(data, node -> lChild);
}
else{
node ->lChild = new Node(data);
}
}
else{
if(node -> rChild){
addElement(data, node -> rChild);
}
else{
node -> rChild = new Node(data);
}
}
}
else{
node -> data = data;
}
}
Here is my BinaryTree.h:
#ifndef __ConnectTree__BinaryTree__
#define __ConnectTree__BinaryTree__
#include <iostream>
class BinaryTree{
private:
class Node{
public:
int data;
Node * lChild;
Node * rChild;
Node();
Node(int data);
};
Node * head;
void addElement(int num, Node * node);
public:
BinaryTree();
BinaryTree(int num);
void addElement(int num);
};
#endif /* defined(__ConnectTree__BinaryTree__) */
Here is my main.cpp where I create a Binary Tree object and insert objects into the tree.
#include <iostream>
#include "BinaryTree.h"
int main(int argc, const char * argv[])
{
// insert code here...
std::cout << "Hello, World!\n";
BinaryTree t;
t.addElement(4);
t.addElement(10);
t.addElement(11);
t.addElement(9);
t.addElement(2);
t.addElement(1);
t.addElement(3);
return 0;
}
The problem is with this line in BinaryTree::Node::Node(int data) implementation:
data = data;
If you still can't find, I'll edit my answer to let you know exact problem.
So for my assignment, I am supposed to implement a Node class that just contains data and pointers to its two siblings and a BinaryTree that reads in these Nodes and creates a binary tree out of them. My problem is pointing to the root of the Tree does not seem to work. Any help you can provide would be appreciated!
Note: The error is found a few lines into the addNode method in the BinaryTree.cpp file which can be found at the end of the question. Also, I am not able to access the value of size either, so I believe this is some sort of weird scope issues I cannot resolve. I also cannot use the "this" keyword in the addNode function.
I am also not allowed to use structs, per my homeworks' instruction.
Node.H
#include <iomanip>
using namespace std;
class Node
{
public:
int data;
Node* leftChild;
Node* rightChild;
Node(int data, Node* leftChild, Node* rightChild);
};
Node.cpp
#include <iomanip>
#include <iostream>
#include "Node.h"
using namespace std;
Node::Node(int data, Node* leftChild, Node* rightChild)
{
this->data = data;
this->leftChild = leftChild;
this->rightChild = rightChild;
}
BinaryTree.H
#include <iomanip>
#include "Node.h"
using namespace std;
class Tree
{
public:
Tree(int data);
void addNode(int data);
void inOrder(Node* N);
protected:
Node* root;
int size;
int data;
private:
int printNode(Node* N);
};
BinaryTree.cpp
#include <iostream>
#include <iomanip>
#include "BinaryTree.h"
using namespace std;
//Tree constructor. Sets the values of data, size, and root.
Tree::Tree(int data)
{
this->data = data;
this->size = 0;
this->root = new Node(data, NULL, NULL);
}
//Adds a node to the current Tree.
void addNode(int data)
{
Node* tempNode = new Node(data, NULL, NULL);
Node* current = root; //THIS IS THE ERROR LINE.
while(current!=NULL)
{
//If the data we are trying to add is already in the Tree
if(current->data == tempNode->data)
{
cout << "Data already in the Tree.";
}
//If the data for the new node is larger than the old
else if(current->data < tempNode->data)
{
//See if the right child is null. If so, add the tree node there.
if(current->rightChild == NULL)
{
current->rightChild = tempNode;
return;
}
//Otherwise, traverse down the right tree.
else
{
current = current->rightChild;
}
}
//The data is smaller than the current node
else
{
//See if the left child is null. If so, add the tree node there.
if(current->leftChild == NULL)
{
current->leftChild = tempNode;
return;
}
//Otherwise, traverse down the left tree
else
{
current = current->leftChild;
}
}//End of leftChild Else
}//End of while
}//End of addNode
void addNode(int data)
should be:
void Tree::addNode(int data)
as it is a member function of class Tree
//Adds a node to the current Tree.
void addNode(int data)
Should be:
//Adds a node to the this Tree
void Tree::addNode(int data)