Inserting a node into a binary search tree in C++ - c++

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.

Related

Creating a binary Tree and search function

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.

How to keep track of layers when traversing a binary tree?

If I need to print out each elements of a binary tree constructed with the struct below. How could I keep track of which layer of elements I am printing?
struct for a binary tree node
For example:
any binary tree
Expected output:
layer 0: 12
layer -1: 28 19
layer -2: 94 32
layer -3: 65 18 72
Solution using queue based on GeeksForGeeks
#include <iostream>
#include <queue>
using namespace std;
// A Binary Tree Node
struct node
{
struct node *left;
int data;
struct node *right;
};
// Iterative method to do level order traversal
// line by line
void printLevelOrder(node *root)
{
// Base Case
if (root == NULL)
return;
// Create an empty queue for level order tarversal
queue<node *> q;
// Enqueue Root and initialize height
q.push(root);
int i = 0;
while (q.empty() == false)
{
cout << "layer " << i << ": ";
// nodeCount (queue size) indicates number
// of nodes at current lelvel.
int nodeCount = q.size();
// Dequeue all nodes of current level and
// Enqueue all nodes of next level
while (nodeCount > 0)
{
node *node = q.front();
cout << node->data << " ";
q.pop();
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
nodeCount--;
}
cout << endl;
--i;
}
}
// Utility function to create a new tree node
node *newNode(int data)
{
node *temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
// Driver program to test above functions
int main()
{
// Create binary tree
node *root = newNode(12);
root->left = newNode(28);
root->right = newNode(19);
root->left->left = newNode(94);
root->left->left->left = newNode(65);
root->left->left->right = newNode(18);
root->right->left = newNode(32);
root->right->left->right = newNode(72);
printLevelOrder(root);
return 0;
}
Solution using recursive function and helper function based on CrazyForCode:
#include <iostream>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
void printLevel(node *, int);
int height(struct node *node);
/* Function to print level order traversal a tree*/
void printLevelOrder(struct node *root)
{
int h = height(root);
int i;
for (i = 1; i <= h; i++){
printf("layer %d: ",i*-1+1);
printLevel(root, i);
cout << endl;
}
}
/* Print nodes at a given level */
void printLevel(struct node *root, int level)
{
if (root == NULL)
return;
if (level == 1)
{
printf("%d ", root->data);
}
else if (level > 1)
{
printLevel(root->left, level - 1);
printLevel(root->right, level - 1);
}
}
/* Compute the "height" of a tree */
int height(struct node *node)
{
if (node == NULL)
return 0;
else
{
int lheight = height(node->left);
int rheight = height(node->right);
if (lheight > rheight)
return (lheight + 1);
else
return (rheight + 1);
}
}
node *newNode(int data)
{
node *temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
int main()
{
// Create binary tree
node *root = newNode(12);
root->left = newNode(28);
root->right = newNode(19);
root->left->left = newNode(94);
root->left->left->left = newNode(65);
root->left->left->right = newNode(18);
root->right->left = newNode(32);
root->right->left->right = newNode(72);
printLevelOrder(root);
return 0;
}

Searching for an object inside a binary search tree

**The trace function is the one I am using to search through the binary search tree it returns the right order of numbers when I search for something within the tree but when I want to see if a number doesn't exist i get segmentation fault **
// Binary search tree
#include <stdio.h>
#include <iostream>
#include <assert.h>
using namespace std;
struct node
{
int data;
node * left;
node * right;
};
node * newNode(int data){
node * newnode = new node();
newnode -> data = data;
newnode -> left = NULL;
newnode -> right = NULL;
return newnode;
}
node* Insert (node * root, int data){
if(root == NULL){
root = newNode(data);
}
else if(data <= root-> data){
root->left = Insert(root->left, data);
}
else{
root -> right = Insert(root->right, data);
}
return root;
};
int Trace(node* root,int find){
node * searcher = root;
if(searcher->data == find){
cout << searcher->data << endl;
}
else if(find <= root -> data){
Trace(searcher->left, find);
cout << searcher ->data<< endl;
}
else if(find >= root -> data){
Trace(searcher->right, find);
cout << searcher ->data << endl;
}
else cout << "not found" << endl;
return searcher-> data;
};
int main(){
node * root = NULL; // creating an empty tree
root = Insert(root, 234234);
root = Insert(root, 2334);
root = Insert(root, 23784);
root = Insert(root, 223);
root = Insert(root, 4244);
root = Insert(root, 673234);
root = Insert(root, 2);
root = Insert(root, 2344);
root = Insert(root, 234);
Trace(root,4244);
return 0;
}
When you are walking through the tree looking for a member that doesn't exist, you'll eventually reach a NULL node. When you try to assess its data, you get a segmentation fault. You can avoid this by checking if the node you are going to assess is valid. For example, change your function Trace to:
int Trace(node* root, int find) {
node * searcher = root;
if(!searcher) {
cout << "Node not found" << endl;
//return something here
}
//rest of function stays the same
}

create a BST of string . error

Inserting just one node to the tree works fine, but on inserting the 2nd node onwards, the program crashes. Here is the code:
#include <iostream>
#include <cstring>
using namespace std;
struct node
{
char* key;
node *left, *right;
};
// A utility function to create a new BST node
node *newNode(const char* item)
{
node *temp =new node;
strcpy(temp->key,item);
temp->left = temp->right = NULL;
return temp;
}
// A utility function to do inorder traversal of BST
void inorder(node *root)
{
if (root!= NULL)
{
inorder(root->left);
cout<<root->key<<endl;
inorder(root->right);
}
}
/* A utility function to insert a new node with given key in BST */
node* insert(node* tnode,const char* key)
{
/* If the tree is empty, return a new node */
if (tnode == NULL)
return newNode(key);
/* Otherwise, recur down the tree */
if (strcmp(key,tnode->key) < 0)
tnode->left = insert(tnode->left, key);
else if (strcmp(key,tnode->key) > 0)
tnode->right = insert(tnode->right, key);
/* return the (unchanged) node pointer */
return tnode;
}
// Driver Program to test above functions*/
int main()
{
node *root = NULL;
char* word[]={"elephant","hi","little","nil",NULL};
root = insert(root,word[0]); //works fine
for(int i=1;word[i];i++)
insert(root,word[i]);
// print inoder traversal of the BST
inorder(root);
return 0;
}
after:
root = insert(root,word[0]);
inorder(root);
o/p: elephant
on inserting 2nd node
crashes
You're not initialising the key array that item will get copied into. Try this:
node *newNode(const char* item)
{
node *temp = new node();
temp->key = new char[strlen(item) + 1];
strcpy(temp->key,item);
temp->left = temp->right = NULL;
return temp;
}
That said, there are some more problems with your code, like no destructors etc. I'd strongly recommend reading some good books/tutorials on programming in C++.

Binary Tree being filled with zeros

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.