C++ Tree could not insert value - c++

I have written this code. But it does not insert and print value. Can anyone check and tell the problem?
struct Node{
int value;
Node* left;
Node* right;
};
class Tree {
Node* root;
public:
Tree insertNode( Node* tree,int val)
{
if(tree==NULL)
{
tree = new Node;
tree->value=val;
tree->left=NULL;
tree->right=NULL;
}
else if (val<=tree->value){
insertNode(tree->left,val);
}
else
{
insertNode(tree->right,val);
}
return *this;
}
insert(int val)
{
insertNode(root, val);
}
void printTree(Node* root)
{
if(!root)
{
cout<<"Tree is empty"<<endl;
return;
}
printTree(root->left);
cout<<root->value;
printTree(root->right);
}
print()
{
printTree(this->root);
}
};
int main(){
Tree* Nodd = new Tree();
Nodd->insert(12);
Nodd->insert(10);
Nodd->print();
}
When i run this program it, just run in the first if statement in the insertNode function. I think, i am missing something and doing something wrong.

Tree insertNode( Node* tree,int val)
In this function you should pass the node pointer by reference to be able to modify the node, so the correct parameter is
Tree insertNode( Node* &tree,int val)

Related

This tree implementation is not showing any output

I have implemented a tree using classes in C++, but the program is not showing any output when I called display function. Can anyone spot the reason?
Output
#include<iostream>
using namespace std;
class TreeNode //node for tree
{
public:
int data;
TreeNode* left;
TreeNode* right;
TreeNode(int val)
{
data=val;
left=NULL;
right=NULL;
}
};
class Tree //class for tree
{
public:
TreeNode *r;
Tree()
{
r=NULL;
}
void insert(int data)
{
TreeNode* new_node=new TreeNode(data);
TreeNode*trav=r;
while(trav!=NULL)
{
if(data>trav->data)
{
if(trav->right==NULL)
{
trav->right=new_node;
break;
}
trav=trav->right;
}
else
{
if(trav->left==NULL)
{
trav->left=new_node;
break;
}
trav=trav->left;
}
}
}
void display()
{
print(r);
}
void print(TreeNode *node)
{
if(node!=NULL)
{
print(node->left);
cout<<node->data<<" ";
print(node->right);
}
}
};
int main() //main function
{
Tree T;
T.insert(10);
T.insert(1);
T.insert(2);
T.insert(100);
T.display();
}
At beginning, 'r' is not assigned, that is, 'r' is NULL pointer.
So In 'Insert' function, no values can be insert to Tree.
I think it is likely that the first input value is to be set as a default value. And then 'r' must be initialized at this point.
class Tree //class for tree
{
public:
TreeNode *r;
Tree()
{
r = NULL;
}
~Tree()
{
release(r);
}
void release(TreeNode * node)
{
if (node != NULL)
{
release(node->left);
release(node->right);
delete node;
node = NULL;
}
}
void insert(int data)
{
if (r == NULL)
{
r= new TreeNode(data);
return;
}
...
And you need to add logic to releasing the all memories allocated to 'r' in the destructor of the 'Tree' class.
Change the Tree constructor to something like this:
Tree(int root_data) {
r = new TreeNode(root_data);
r->left=NULL;
r->right=NULL;
}
And replace
Tree T;
with
int some_value;
Tree T(some_value);

How to call a function method recursively in classes in c++?

So, I started learning and reading about OOP not so long ago, I've been implementing all the data structures I know using classes and objects just for overall practice and to get comfortable with using OOP in c++.
I'm implementing the tree data structure and I've been wondering how to call a method recursively(I'm aware that I have to pass in an argument) so that when I create an object in main and call a specific method it's written like the following a.inorder(); and not a.inorder(root) since root is a private attribute.
Is this possible ?
My code:
#include<iostream>
using namespace std;
struct node
{
int data;
node* left;
node* right;
};
class tree
{
private:
node* root;
public:
tree();
tree(int val);
void insert(int val);
void preorder();
void postorder();
void inorder();
int count();
};
tree::tree() : root { NULL }
{
}
tree::tree(int val)
{
root = new node;
root->data = val;
root->left = root->right = NULL;
}
void tree::insert(int val)
{
if (!root)
{
root = new node;
root->data = val;
root->left = root->right = NULL;
}
else
{
node* t = root;
node* p = NULL;
while (t)
{
p = t;
if (val > root->data)
t = root->right;
else
t = root->left;
}
t = new node;
t->data = val;
t->left = t->right = NULL;
if (p->data > t->data)
p->left = t;
else
p->right = t;
}
}
void tree::preorder()
{
if (root)
{
}
}
In your design, a node refers to itself. Since it is the node object that is recursive, you could define the recursive method on node:
struct node
{
int data;
node* left;
node* right;
void preorder() {
//...
left->preorder();
right->preorder();
}
};
And then, tree::preorder() would just dispatch a call to root->preorder().
Write a private static recursive function passing to it the pointer to the root node and call the function from the corresponding public non-static member function.
For example
public:
std::ostream & preorder( std::ostream &os = std::cout ) const
{
return preorder( root, os );
}
//...
private:
static std::ostream & preorder( const node *root, std::ostream &os );
//...
This is a comment rather than an actual answer, as it addresses a different issue than you are asking about. However, it is too long for a comment space, that's why I post it here.
I suppose you erroneously refer to root in this part
while (t)
{
p = t;
if (val > root->data)
t = root->right;
else
t = root->left;
}
IMHO it should look like this:
while (t)
{
p = t;
if (val > t->data)
t = t->right;
else
t = t->left;
}
Also compare the code to seek a place for insert with a code that makes an actual insertion:
if (p->data > t->data)
p->left = t;
else
p->right = t;
You've put a comparison subexpressions in reversed order - when seeking, you test whether the new value is greater than that in an existing node, but when inserting, you test whether the existing value is greater than the new one. If they differ, the code will work OK, because you also swapped left and right in the 'then' and 'else' branch.
However, if the values appear equal, the execution control will go to 'else' in both places. As a result the testing code may stop at empty left pointer, but then a new node would get appended to the right, which was not tested for being NULL.
Why would the tree class do intrinsic operations on node? The node class knows best the node's internal structure, so let it initialize itself. This will also help you to stick to the DRY principle and, indirectly, to the KISS principle, as well as the Single-responsibility principle.
struct node
{
int data;
node* left;
node* right;
node(int val) : data(val), left(NULL), right(NULL) {}
};
class tree
{
private:
node* root;
public:
tree();
tree(int val);
void insert(int val);
};
tree::tree() : root { NULL }
{
}
tree::tree(int val) : root(new node(val))
{
}
void tree::insert(int val)
{
if (!root)
{
root = new node(val);
}
else
{
node* t = root;
node* p = NULL;
while (t)
{
p = t;
if (val < t->data)
t = t->left;
else
t = t->right;
}
t = new node(val);
if (t->data < p->data)
p->left = t;
else
p->right = t;
}
}
Additionally, you can make insert recursive, too.
struct node
{
int data;
node* left;
node* right;
node(int val) : data(val), left(NULL), right(NULL) {}
};
class tree
{
private:
node* root;
public:
tree();
tree(int val);
void insert(int val);
protected:
void insertat(node* p, int val);
};
void tree::insert(int val)
{
if (!root)
root = new node(val);
else
insertat(root, val);
}
void tree::insertat(node* t, int val);
{
if (val < t->data)
{
if (t->left)
insertat(t->left, val);
else
t->left = new node(val);
}
else
{
if (t->right)
insertat(t->right, val);
else
t->right = new node(val);
}
}

Deleting Node in Binary Search Tree

I have written code to delete a node in Binary Search Tree.
Code :
#include<iostream>
using namespace std;
struct Node {
int value;
Node* left;
Node* right;
};
Node* GetNewNode(int data) {
Node* newNode = new Node();
newNode->value = data;
newNode->left = newNode->right = NULL;
return newNode;
}
void Insert(Node* &root,int x)
{
if(root==NULL) root=GetNewNode(x);
else if(x>root->value) Insert(root->right,x);
else Insert(root->left,x);
}
Node* Search(Node* root,int x)
{
if(root->value==x) return root ;
else if(root->value>x) Search(root->left,x);
else if(root->value<x) Search(root->right,x);
}
Node* Searchmin(Node* root)
{
if(root==NULL) cout<<"Empty tree"<<endl;
if(root->left==NULL) return root;
else Searchmin(root->left);
}
void Inorder(Node* root)
{
if(root==NULL) return;
else {
Inorder(root->left);
cout<<root->value<<endl;
Inorder(root->right);
}
}
Node* deleteNode(Node* root, int x)
{
Node* nodeptr;
nodeptr=Search(root,x);
if(nodeptr->left==NULL && nodeptr->right==NULL) return nodeptr;
else if(nodeptr->left==NULL && nodeptr->right!=NULL)
{
nodeptr->value=nodeptr->right->value;
nodeptr=nodeptr->right;
return nodeptr;
}
else if(nodeptr->right==NULL && nodeptr->left!=NULL)
{
nodeptr->value=nodeptr->left->value;
nodeptr=nodeptr->left;
return nodeptr;
}
else{
nodeptr->value=Searchmin(nodeptr->right)->value;
deleteNode(nodeptr->right,nodeptr->value);
return nodeptr;}
}
int main()
{
Node* root=NULL;
Insert(root,20);
Insert(root,15);
Insert(root,25);
Insert(root,10);
Insert(root,16);
Insert(root,7);
Inorder(root);
Node* x=deleteNode(root,7);
delete x;
Inorder(root);
}
Compiler doesn't show any syntax error either. The program is crashing. Its not even deleting leaf node. I can't find the error. Please help.
(These lines are just to extend length of question because stackoverflow was not accepting generating error in question on lines of long code and short description.)
The first thing your delete function does is call search, and what's the first thing search does?
Node* Search(Node* root,int x)
{
if(root->value==x) return root ;
Search immediately dereferences root. It never checks for a null pointer. This means it's guaranteed your search function will dereference a null pointer if there is no node in the tree to be found.

Rebuild a binary tree from pre--order and min-order transverse sequence, error in re-build procedure

The input is preOrder:BCAD and midOrder: CBAD, but there is error in the recursive build function. If my guess is right, the while body can't jump out due to certain error, but I have no idea what the error exactly is.
#include <iostream>
using namespace std;
struct Node
{
char data;
Node* left;
Node* right;
Node(char d=0, Node* l=NULL, Node* r=NULL):data(d),left(l),right(r) {}
};
void recoverTree(char* pre, char* mid, Node* root);
void postTranverse(Node* root);
void clean(Node* root);
int main()
{
char preArr[27], midArr[27];
while(cin>>preArr>>midArr)
{
Node* root;
recoverTree(preArr,midArr,root);
postTranverse(root);
clean(root);
}
return 0;
}
void recoverTree(char* pre, char* mid, Node* root)//build binary tree from given sequence
{
char* midTemp=mid;
if(*mid==0)
{
root=NULL;
return;
}
while(true) //loop can't jump out
{
if(*pre==*midTemp)
{
root=new Node(*pre);
*midTemp=0; //how to mark to stop the recursion, wrong?
break;
}
++midTemp;
}
recoverTree(pre+1,mid,root->left);
recoverTree(pre+1,midTemp+1,root->right);
}
void postTranverse(Node* root)// post tranverse the tree
{
if(root==NULL)
return;
//if(root->left!=NULL)
postTranverse(root->left);
//if(root->right!=NULL)
postTranverse(root->right);
cout<<root->data;
}
void clean(Node* root) //release memory in heap
{
if(root->left!=NULL)
clean(root->left);
if(root->right!=NULL)
clean(root->right);
delete root;
}

Use of reference in C++

I am writing code to solve the "Recover Binary Search Tree" problem.
https://oj.leetcode.com/problems/recover-binary-search-tree/
And first I wrote this code to put three pointers out of the recoverTree function like this:
class Solution {
public:
TreeNode *pre;
TreeNode *first;
TreeNode *second;
void recoverTree(TreeNode *root) {
inOrder(root);
int temp = first->val;
first->val = second->val;
second->val = temp;
return;
}
void inOrder(TreeNode *root) {
if (!root) return;
inOrder(root->left);
if (!pre) {
pre = root;
} else {
if (pre->val > root->val) {
if (!first) first = pre;
second = root;
}
pre = root;
}
inOrder(root->right);
}
};
It works fine and past all the tests. And then I was thinking maybe not putting the definitions of three pointers outside the function. So I wrote something like this:
class Solution {
public:
void recoverTree(TreeNode *root) {
TreeNode *pre;
TreeNode *first;
TreeNode *second;
inOrder(root, pre, first, second);
int temp = first->val;
first->val = second->val;
second->val = temp;
return;
}
void inOrder(TreeNode *root, TreeNode *&pre, TreeNode *&first, TreeNode *&second) {
if (!root) return;
inOrder(root->left, pre, first, second);
if (!pre) {
pre = root;
} else {
if (pre->val > root->val) {
if (!first) first = pre;
second = root;
}
pre = root;
}
inOrder(root->right, pre, first, second);
}
};
But this doesn't work. Is there anything wrong with my usage of reference or anything else caused the error?