The code that I tried to print all root to leaf paths in a Binary Tree.
#include<iostream>
#include<stack>
using namespace std;
bool visited[100];
void intilize(){
for(int i=0;i<100;i++)
visited[i]=false;
}
struct node
{
int data;
struct node *left,*right;
};
struct node* createNode(int k)
{
struct node* temp = new node;
temp->left = NULL;
temp->right = NULL;
temp->data = k;
return temp;
}
stack<node*> s,s1;
void print(){
while(!s.empty()){
s1.push(s.top());
s.pop();
}
while(!s1.empty()){
struct node* a= s1.top();
cout<<a->data<<" ";
s1.pop();
s.push(a);
if(s1.empty())
return;
}
}
void printpath(struct node* node){
if(node==NULL) return;
s.push(node);
while(!s.empty()){
struct node* top=s.top();
visited[top->data]=true;
if(top->left!=NULL&&visited[top->left->data]==false)
printpath(top->left);
else if(top->right!=NULL&&visited[top->right->data]==false)
printpath(top->right);
else if(top->left==NULL&&top->right==NULL){
print();
cout<<"\n";
}
s.pop();
}
}
int main() {
struct node* root = createNode(50);
root->left = createNode(7);
root->right = createNode(2);
root->right->left = createNode(1);
root->right->right = createNode(30);
root->right->right->right = createNode(40);
root->right->left->left = createNode(10);
root->right->left->left->left = createNode(12);
intilize();
printpath(root);
return 0;
}
The code gives segmentation fault because there is some issue with the termination condition.
Can someone help me in figuring out the problem.
That approach is over-complicated, and fragile.
A separate stack is not needed for this.
The separate "visible" array is not needed for this.
All that's needed is a stock recursive visitor that recursively descends into this tree, that also takes an additional parameter to a structure that's dynamically built on the stack, which builds the path to the root on the fly, using a link list that goes something like this:
struct path_to_root {
struct path_to_root *next;
struct node *n;
};
Now, all that's needed to print a path to each leaf note is a bog-standard visitor, that recursively iterates over the tree, and this additional parameter. Here's a rough idea of the general approach:
void printpath(struct node *n, struct path_to_root *p)
{
struct path_to_root pnext;
if (!n)
return;
if (!n->left && !n->right)
{
/* Your homework assignment here is to print the path that's in "p" */
}
pnext.n=n;
pnext.next=p;
printpath(n->left, &pnext);
printpath(n->right, &pnext);
}
And this would be invoked as:
printpath(root, NULL);
Your homework assignment, as noted, is to implement the actual code that prints the path to the leaf, using the p parameter, in the space indicated. At that point, the path to the leaf will be found in the p parameter.
Now, one tricky part here is that p will be the leaf's parent, p->next will be its grandparent, and so on. So the path is from the bottom to the top, not top to bottom, but that's a minor detail, that can be handled in the print code.
Or, alternatively, it wouldn't be too much extra work to dynamically build the path to the leaf from top to bottom, in the same manner.
Related
Try to make tree , have a some troubles, first it's print function - it's print not integers that i put, but print random numbers;
Another trouble its append child - its works only one times;
Will be happy if you will help me with this task.
And also give some good articles about linked lists, trees on c and c++;
#include <iostream>
#include <stdio.h>
using namespace std;
struct Node
{
void* m_pPayload;
Node* m_pParent;
Node* m_Children;
};
struct Person
{
int m_Id;
};
//typedef bool (*NodeComparator)(void* pValue, void* pPayload);
/*bool Comp(void* pValue, void* pPayload)
{
Person* pVal = (Person*)pValue;
Person* pPay = (Person*)pPayload;
if (pVal->m_Id == pPay->m_Id)
return true;
else
return false;
}
*/
Node* NewNode(void* pPayload)
{
Node* pNode = new Node;
pNode->m_pParent = nullptr;
pNode->m_Children = 0;
pNode->m_pPayload = pPayload;
return pNode;
}
Person* NewPerson(int id)
{
Person* p = new Person;
p->m_Id = id;
return p;
}
//Node* FindNode(Node* pParent, Node* m_pPayload, NodeComparator comparator);
void AppendChild(Node* pParent, Node* pNode)
{
if (pParent->m_Children == NULL)
pParent->m_Children = pNode;
}
void print(Node* head)
{
Node* current_node = head;
while (current_node != NULL)
{
printf("%d\n ", current_node->m_pPayload);
current_node = current_node->m_Children;
}
}
int main()
{
Node* T = new Node;
T = NewNode(NewPerson(5));
AppendChild(T, NewNode(NewPerson(11)));
AppendChild(T, NewNode(NewPerson(15)));
print(T);
}
printf("%d\n ", current_node->m_pPayload)
is incorrect. %d wants an integer and it's being given a pointer. The results will be unusual, and likely appear to be random garbage.
printf("%d\n ", ((Person*)current_node->m_pPayload)->m_Id);
^ ^
| Get id from Person
treat payload pointer as pointer to Person
will solve the immediate problem.
Your code actually seems to be pretty messed up with a lot of things going on, here sharing my own commented code from few years back, hope it helps
#include <bits/stdc++.h>
using namespace std;
// Single node representation
struct node {
int data;
node *left, *right;
};
// Declaring temp for refference and root to hold root node
node *root, *temp;
// This function only generates a node and return it to the calling function with data stored in it
node* generateNode(int data){
temp = new node();
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
// This function actually adds node to the tree
node* addNode(int data, node *ptr = root){
// If the node passed as ptr is NULL
if(ptr == NULL){
ptr = generateNode(data);
return ptr;
}
// Condition to check in which side the data will fit in the tree
else if(ptr->data < data)
//if its in right, calling this function recursively, with the right part of the tree as the root tree
ptr->right = addNode(data, ptr->right);
else
//In case the data fits in left
ptr->left = addNode(data, ptr->left);
//Note: if there is no data in left or roght depending on the data's valid position, this function will get called with NULL as second argument and then the first condition will get triggered
//returning the tree after appending the child
return ptr;
}
//Driver function
int main ()
{
int c, data;
for (;;){
cin >> c;
switch(c){
case 1:
cout << "enter data: ";
cin >> data;
//Updating root as the tree returned by the addNode function after adding a node
root = addNode(data);
break;
default:
exit(0);
break;
}
}
return 0;
}
Please find below a piece of code that should easily get you started. It compiles and it traverse the tree using recursion.
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace std;
struct Node
{
int m_Id;
vector<Node*> m_Children;
Node(const int& id){
m_Id = id;
}
void AppendChild(Node* pNode) {
m_Children.push_back(pNode);
}
void Print() {
printf("%d\n ", m_Id);
}
};
void traverse(Node* head)
{
Node* current_node = head;
current_node->Print();
for(int i = 0; i<current_node->m_Children.size(); i++) {
traverse(current_node->m_Children[i]);
}
}
int main()
{
Node* T0 = new Node(0);
Node* T10 = new Node(10);
T10->AppendChild(new Node(20));
Node* T11 = new Node(11);
Node* T12 = new Node(12);
Node* T22 = new Node(22);
T22->AppendChild(new Node(33));
T12->AppendChild(T22);
T0->AppendChild(T10);
T0->AppendChild(T11);
T0->AppendChild(T12);
traverse(T0);
}
First for printing the node value
Talking about the current mistake that you had committed is in the above code is:
You have not mentioned its pointer to its child (specifically right or left). Due to which it is showing garbage value every time.
For e.g.: print( node->left);
Since you need to type caste it properly to show the data of data.
For e.g.: printf("%d\n ", ((Person*)current_node->m_pPayload)->m_Id);
There is a specific direction in which you want to print data. For trees, there are three directions in which you can print the data of the node and they are as follow:
Left order or Inorder traversal
Preorder traversal
Postorder traversal
This can give you better information about traversal.
Secondly for adding the node to a tree
This might help explain it better.
#include<stack>
#include<iostream>
class Tree{
private:
struct tree{
int val;
tree * lChild;
tree * rChild;
tree * Parent;
};
tree *root;
public:
Tree();
void insert(int x);
};
Tree::Tree(){
root = NULL;
std::cout<<"ROOT inside constructor : "<<root<<std::endl;
}
void Tree::insert(int x){
tree *wst;
wst->val = x;
wst->lChild = NULL;
wst->rChild = NULL;
tree *temp = root;
tree *p = NULL;
std::cout<<"ROOT inside insert : "<<root<<std::endl;
while(temp != NULL){
p = temp;
if(x < temp->val)
temp = temp->lChild;
else
temp = temp->rChild;
}
std::cout<<x<<std::endl;
wst->Parent = p;
if(p == NULL){
root = wst;
}
else{
if(x < p->val)
p->lChild = wst;
else
p->rChild = wst;
}
}
int main(){
Tree tree;
tree.insert(404);
}
I want to check if pointer root is equal to NULL, but it does not seems too work. It seems like the pointer changes from 0 to 0x4 when I am inside the method insert. How can I check if pointer of struct is equal NULL?
EDIT In the insert method if tree doesn't have any nodes it should not enter first while loop, as root should be equall NULL. And my problem is that it enters this loop anyway and crashes when it checks for temp childrens(that are still not defined).
What does wst point to?
tree *wst;
wst->val = x;
wst->lChild = NULL;
wst->rChild = NULL;
// [...]
wst->Parent = p;
Whoops! Your program has undefined behaviour. No wonder it crashes. :)
You probably need tree* wst = new tree(); there. Don't forget to delete your nodes in the Tree destructor, too!
And I'd advise against having a type Tree plus a type tree; perhaps call the latter Node instead?
Hi guys I have a doubt in inserting a new node in BST. In the addNode module I am trying to insert an element in the BST, but each time while adding a new node it is adding to the same root node which I passed from main function initially without traversing inside the tree.
This is the code which I have written.
#include<stdio.h>
#include<stdlib.h>
#include<cstdio>
#include<iostream>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
struct node* newNode(int data)
{
node* temp = (node*)malloc(sizeof(struct node));
//struct temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return(temp);
};
int addNode(node *dest, node *root)
{
if(root == NULL)
{
cout<<"adding data to node for "<< dest->data<<endl;
root = dest;
cout<<"ROOT VALUE = root->data "<<root->data<<endl;
return 1;
}
if(dest->data > root->data)
{
cout<<"Traverse right for "<<dest->data<<endl;
addNode(dest, root->right);
}
else if(dest->data < root->data)
{
cout<<"Traverse left for "<<dest->data<<endl;
addNode(dest, root->left);
}
}
void printNodes(node *root)
{
if(root != NULL)
{
printNodes(root->left);
if(root->left != NULL && root->right != NULL)
std::cout<< root->data <<" ";
printNodes(root->right);
}
}
int main()
{
int i, j, k, flag;
int arr[6] = {4, 2,8, 1, 0, 10};
node *start = newNode(arr[0]);
for(i = 1; i < 6; i++)
{
node *newOne = newNode(0);
newOne->data = arr[i];
cout<<"NODE DATA - start->data "<<start->data;
if(addNode(newOne, start))
std::cout<<"\nNode added"<<endl;
}
printNodes(start);
return 1;
}
I am quite new to trees concept as well as pointers concept in trees. Any help is appreciated and thank you.
... but each time while adding a new node it is adding to the same root
node
This is because you are adding it always to the same root, as here
if(addNode(newOne, start))
start is always the same. You could make addNode return the new root and call it like that:
start = addNode(newOne,start);
I'll leave it to you to implement it.
Note that parameters are always passed by value in c++ (unless you pass-by-reference), thus changing the parameter inside the method, root = dest;, has no effect on the start in main.
This is my first time working with trees. I wrote a c++ code, but it says Segmentation fault (core dumped) , As far as I searched, this error comes from accessing a memory location that may be NULL. I tried 'new' keyword as malloc() should be avoided in c++, But still I didn't get how to resolve this in my code.
# include<iostream>
using namespace std;
struct node
{
int data;
node *left;
node *right;
}*next;
int k=0;
void tree(int i,/*struct*/ node *next = new node)
{
++k; --i;
if (i==0)
return;
//next = new node;
next->data = k*k;
next->left = NULL;
next->right = NULL;
tree(i, next->left);
tree(i, next->right);
return ;
}
void display (node* next)
{
cout<<next->data<<" ";
if (next->left!=NULL)
{
display(next->left);
display(next->right);
}
}
int main()
{
int h;
cout<<"Enter the expected height of tree : ";
cin>>h;
node *root;
root = new node;
root->data=0;
root->left=NULL;
root->right=NULL;
tree(h, (root->left));
tree(h, (root->right));
cout<<root->data<<" ";
display(root->left);
display(root->right);
return 0;
}
There are serious problems with this code. In particular, here:
void display (node* next)
{
cout<<next->data<<" ";
if (next->left!=NULL)
{
...
}
}
You dereference next without ever checking to see whether it's null. And it will be null. That's enough to explain the error you see.
I say that it will be null because of this:
void tree(int i,/*struct*/ node *next = new node)
{
...
return ;
}
...
root->left=NULL;
...
tree(h, (root->left));
...
display(root->left);
The tree function takes its second argument by value-- that means that it does not change the value of root->left. You then call display with a null argument. I suspect that you think void tree(int i,/*struct*/ node *next = new node) means something other than what it actually means.
More fundamentally, you must review the two ways to pass an argument, by reference and by value.
More fundamentally still, you must start with a small, simple program and build up in small steps, rather than trying to write a big complex program all at once.
#include <iostream>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
void tree(int i, struct node **root, int k)
{
if (i < 1)
return;
*root = new struct node;
(*root)->data = k*k;
(*root)->left = NULL;
(*root)->right = NULL;
tree(i - 1, &((*root)->left), k + 1);
tree(i - 1, &((*root)->right), k + 1);
}
void display(struct node *root)
{
if (root == NULL)
return;
cout << root->data << " ";
if (root->left != NULL)
display(root->left);
if (root->right != NULL)
display(root->right);
}
int main()
{
struct node *root;
int h;
cout<<"Enter the expected height of tree : ";
cin>>h;
tree(h, &root, 0);
display(root);
return 0;
}
I think you should do some more read up on how pointers works: http://www.tutorialspoint.com/cprogramming/c_pointers.htm
When you where calling tree(h, root->left) you actually just send the pointers value "NULL" == 0x0. As you want to allocate memory for it you should send a reference to the pointer. Hence &root and &((*root)->left). In the display function you have to check for NULL values both for left and right.
The code above is only improved and doesn't handle any freeing of memory, to be able to do that, traverse the tree and use delete on all leafs and work you back to the root.
The following is the code to converted a preorder traversal of a Binary Search Tree to the original tree.
The following code takes an array of integers, which represent the pre order traversal of a a Binary search tree. The root of the construct tree is returned.
struct Node* constructTree(int pre[], int size)
{
stack<struct Node* > s;
int i;
struct Node* root=newNode(pre[0]);
struct Node* temp;
struct Node* top_node;
s.push(root);
for(i=1;i<size;i++)
{
temp=NULL;
while(!s.empty()&&pre[i]>(s.top()->data))
{
temp=s.top();
s.pop();
}
if(temp==NULL)
{
top_node=s.top();
top_node->left=newNode(pre[i]);
s.push(top_node->left);
}else
{
temp->right=newNode(pre[i]);
s.push(temp->right);
}
}
return root;
}
Source: http://www.geeksforgeeks.org/construct-bst-from-given-preorder-traversal-set-2/
I have trouble understanding this code. Can anybody help me understand the following:
At any given iteration, what values are stored in the stack, in relation to the current value being pointed out by pre[i]
Is there any other iterative method for constructing a BST from a given preorder traversal?
Thank you.
After the iteration where the node containing pre[i] is constructed, the stack contains that node on top, under which its leafmost to rootmost ancestors with exactly one child are stored top to bottom.
Check if this works:
public:
TreeNode* bstFromPreorder(vector<int>& preorder) {
TreeNode *root = new TreeNode(preorder[0]);
stack<TreeNode*> nodes;
nodes.push(root);
for (int i = 1; i < preorder.size(); i++) {
TreeNode *temp = new TreeNode(preorder[i]);
if (temp->val < nodes.top()->val)
nodes.top()->left = temp;
else {
TreeNode *prev;
while (!nodes.empty() && nodes.top()->val < temp->val) {
prev = nodes.top();
nodes.pop();
}
prev->right = temp;
}
nodes.push(temp);
}
return root;
}