I have a while loop which continuously takes integers until -1 is entered. Those elements must be inserted into a binary tree (not a BST). If it was a BST, we have a condition for where to insert the new node. But how can I construct a binary tree?
I mean if nodes are 1,2,3,4,5,6..., then
1 is the root, 2 and 3 are the left and right children of node 1,
4 and 5 are the left and right children of node 2, and 6 is left child of node 3, like this:
if(root==NULL)
root= newnode;
else{
if (root->left==NULL)
root->left= insert(root->left,element);
else
root->right= insert(root->right,element);
}
return root;
How do I create a tree like this?
One simple way of doing this is use level order traversal.
Whenever you find a node whose left or right child is NULL, attach the new node as a child of that node; if both left and right are NULL, attach as left child, else attach as right child.
tree_node *insert_node_in_tree(tree_node *root, node new_node) {
if(root == NULL)
return new_node;
queue <tree_node * > qu;
tree_node *temp;
qu.push(root);
while(!(qu.empty())) {
temp = qu.front();
qu.pop();
if(temp->left == NULL || temp->right == NULL)
break;
qu.push(temp->left);
qu.push(temp->right);
}
if(temp->left == NULL)
temp->left = new_node;
else
temp->right = new_node;
return root;
}
The algorithm outlined by WhozCraig in his comment can be realized by the code:
/* Create a binary tree with nodes presented in BFS order */
#include <cassert>
#include <iostream>
#include <vector>
#include <iomanip>
using std::vector;
using std::cout;
using std::cin;
using std::ostream;
using std::setw;
struct node
{
int data;
node *left;
node *right;
node(int n) : data(n), left(0), right(0) { }
};
void print_bt(const node *root);
int main()
{
vector<node> v;
int n;
// Read data to EOF or a negative value
while (cin >> n && n >= 0)
v.push_back(node(n));
// Create binary tree
for (size_t i = 0; i < v.size()/2; i++)
{
assert(2*i+1 < v.size());
v[i].left = &v[2*i+1];
if (2*i+2 < v.size())
v[i].right = &v[2*i+2];
}
// Print binary tree
print_bt(&v[0]);
return 0;
}
// print_bt() presents the data so that if you mentally rotate the
// output through 90º clockwise (so the root is at the top), then the
// left child appears on the left and the right on the right. Reversing
// the order of left/right leaves that as somewhat confusing.
void print_bt(const node *root)
{
static int level = 0;
if (root != nullptr)
{
level++;
print_bt(root->right);
cout << setw(4*level) << root->data << '\n';
print_bt(root->left);
level--;
}
}
For example, given the numbers 1 to 6 as input, it produces:
3
6
1
5
2
4
and given the numbers 1 to 15 as input, it produces:
15
7
14
3
13
6
12
1
11
5
10
2
9
4
8
It helps if you visualize the tree rotated 90º clockwise, so that the 1 is at the top.
Related
I'm trying to solve the problem of Vertical Order Traversal of Binary Tree using map and queue. I did solve it using a recursive way, but I'm not getting the same answer using the iterative way.
10
/ \
7 4
/ \ / \
3 11 14 6
Approach :
First I declared an integer that stores horizontal distance from the root node.
Horizontal distance means that the left part from the root will be considered as -1, -2 and so on, like a negative X axis, where the root is origin and starts from 0. So node 7 will be given -1, 3 will be given -2. However, 10, 11, 14 will be given 0 as they are not away from root node but lie in the same position. And towards the right, distance will become positive so 4 will get distance 1, 6 will get 2 and so on.
At first, I pushed the root in the queue and updated the horizontal distance as 0. After that, I added horizontal distance as key and root data as value in the map. And finally, I poped the root from the queue and I checked for its left and right child, if left or right child was available, I pushed the left and right child in the queue respectively and updated horizontal distance accordingly. Then I followed the same procedure for the complete binary tree.
And then, I just traversed through the second part of the map to get the answer.
The Answer should be :
3
7
10 11 14
4
6
The Answer I received is :
10 7 4 3 11 14 6
Here is my Code :
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
struct Node
{
int data;
Node *left;
Node *right;
Node(int val)
{
data = val;
left = NULL;
right = NULL;
}
};
map<int, vector<int>> verticalPrint(Node *root)
{
queue<Node *> qi;
map<int, vector<int>> mp;
int Hd = 0;
qi.push(root);
while (!qi.empty())
{
Node *temp = qi.front();
mp[Hd].push_back(temp->data);
qi.pop();
if (temp->left != NULL)
{
qi.push(temp->left);
Hd -= 1;
}
if (temp->right != NULL)
{
qi.push(temp->right);
Hd += 1;
}
}
return mp;
}
int main()
{
Node *root = new Node(10);
root->left = new Node(7);
root->right = new Node(4);
root->left->left = new Node(3);
root->left->right = new Node(11);
root->right->left = new Node(14);
root->right->right = new Node(6);
map<int, vector<int>> mp = verticalPrint(root);
map<int, vector<int>>::iterator it;
for (it = mp.begin(); it != mp.end(); it++)
{
for (int i = 0; i < it->second.size(); i++)
{
cout << it->second[i] << " ";
}
cout << endl;
}
return 0;
}
You cannot use a single Hd variable like that. Note how in the first iteration, Hd will go to -1 and back to 0 because the root has both a left and right child. So in the next iteration you start again with 0, yet the node that you pull from the queue has nothing to do with that value of Hd.
Instead, put pairs in the queue: a combination of node and its corresponding horizontal distance. Then it will work fine:
map<int, vector<int>> verticalPrint(Node *root)
{
queue<pair<int, Node *>> qi;
map<int, vector<int>> mp;
qi.push({0, root});
while (!qi.empty())
{
pair<int, Node*> item = qi.front();
int hd = item.first;
Node * temp = item.second;
mp[hd].push_back(temp->data);
qi.pop();
if (temp->left != NULL)
{
qi.push({hd - 1, temp->left});
}
if (temp->right != NULL)
{
qi.push({ hd+1, temp->right});
}
}
return mp;
}
I just wanted to implement a TreeNode class that works similar to that of a struct node for a tree implementation.
Everything is working fine except for the output that is including 0 at the beginning of the inOrder traversal. Can anyone please explain it to me why is that happening?
Input:
22,1,2,3,5,4,11,20,19,24,21
Output:
0 1 2 3 4 5 11 19 20 21 22 24
#include <bits/stdc++.h>
using namespace std;
class TreeNode{
public:
int data;
TreeNode* left;
TreeNode* right;
TreeNode(){
left = NULL;
right = NULL;
}
TreeNode(int val){
data = val;
left = NULL;
right = NULL;
}
};
void insertInorder(TreeNode* cur, int d){
if(d <= cur->data){
if(cur->left == NULL)
cur->left = new TreeNode(d);
else
insertInorder(cur->left,d);
}
else{
if(cur->right == NULL)
cur->right = new TreeNode(d);
else
insertInorder(cur->right,d);
}
}
TreeNode* makeTree(vector<int> v){
TreeNode* root = NULL;
for(int start = 0; start <= v.size(); start++){
if(start == 0){
root = new TreeNode();
root->data = v[0];
}
insertInorder(root,v[start]);
}
return root;
}
void printInorder(TreeNode* node)
{
if (node == NULL)
return;
/* first recur on left child */
printInorder(node->left);
/* then print the data of node */
cout << node->data << " ";
/* now recur on right child */
printInorder(node->right);
}
int main(){
vector<int> x = {22,1,2,3,5,4,11,20,19,24,21};
TreeNode* r = makeTree(x);
printInorder(r);
return 0;
}
Edit:
To the people visiting this questions at a future date. Better practices states that we shouldn't use
#include <bits/stdc++.h>
using namespace std;
Using namespace std can result into future namespace collisions in the code. For reference here.
I did the same mistake but I won't be doing this from now on.
Please refer to the link provided by #Jabberwocky here
I have a code that can determine tree height by hard coding it's values
I tried using container like structures but still was not successful, instead of posting what I have tried on the part of accepting tree nodes fro the Input which is actually messy,I decided to post the code with hard coded tree nodes, what I need is for the program to accept tree nodes from the keyboard with the following helper description for input
Input:
The first line is an integer N indicating the number of nodes.
For each of the next few lines, there are two integers include a and b.b is a child of a.
example:
5 // number of nodes
1 2
1 3
3 4
3 5
in which the height will be 3
// C++ program to find height of tree
#include <bits/stdc++.h>
using namespace std;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class node
{
public:
int data;
node* left;
node* right;
};
/* Compute the "maxDepth" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int maxDepth(node* node)
{
if (node == NULL)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
/* use the larger one */
if (lDepth > rDepth)
return(lDepth + 1);
else return(rDepth + 1);
}
}
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
node* newNode(int data)
{
node* Node = new node();
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return(Node);
}
// Driver code
int main()
{
node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
cout << "Height of tree is " << maxDepth(root);
return 0;
}
Since the input identifies the parent node by its data value, we need a helper function to find it:
node *findNode(node *node, int data)
{
if (!node) return 0;
if (node->data == data) return node;
class node *found;
(found = findNode(node->left, data)) || (found = findNode(node->right, data));
return found;
}
Then we can code the input processing, e. g.:
node *node, *root = 0; // initially empty
int nn, a, b;
cin>>nn;
while (cin>>a>>b)
{
if (!root)
root = newNode(a),
node = root;
else
node = findNode(root, a);
if (!node->left) node->left = newNode(b);
else node->right = newNode(b);
}
Hi!
I would like to know what can be the if statement's condition so all left branches of a binary tree could be printed using postorder traverse.
template <class dataType>
void PrintLeft (BinaryTree <dataType> * bt) {
if (!(bt == NULL))
{
//traverse left child
PrintLeft (bt->left());
//traverse right child
PrintLeft (bt->right());
//visit tree
if(/*no idea what goes here*/)
cout << bt->getData() <<"\t";
}
}
I understand that you want to visit only the nodes that were seen from a left branch. Since it is postorder, you must visit them when you get back on the right branch. So, such as said by πάντα ῥεῖ, you can use a boolean flag indicating from which type of branch you have discovered the node.
So a possible way would be as follows:
using Node = BinaryTree <int>; // or another type supporting << operator
void printLeft(Node * root, bool from_left)
{
if (root == nullptr) // empty tree?
return;
printLeft(root->left, true); // this node must be visited in postorder
printLeft(root->right, false); // this one must not be visited in postorder
if (from_left) // was root seen from a left arc?
cout << root->getData() << "\t"; // visit only if was seen from a left branch
}
There is an ambiguity with the root. I assume that it must not be printed because it is not reached from a left branch (nor right too).
So the first call should be:
printLeft(root, false);
Just as verification, for this tree:
The algorithm produces as left postorder traversal the following sequence
0 1 4 3 8 9 12 11 16 18
here goes code for postorder traversing
void postorder(BinaryTree *bt)
{
if(bt!=NULL)
{
postorder(t->lp);
postorder(t->rp);
//No Code Goes Here
cout<<bt->data<<"\t";
}
}
Try This One
void leftViewUtil(struct node *root, int level, int *max_level)
{
// Base Case
if (root==NULL) return;
// If this is the first node of its level
if (*max_level < level)
{
printf("%d\t", root->data);
*max_level = level;
}
// Recur for left and right subtrees
leftViewUtil(root->left, level+1, max_level);
leftViewUtil(root->right, level+1, max_level);
}
// A wrapper over leftViewUtil()
void leftView(struct node *root)
{
int max_level = 0;
leftViewUtil(root, 1, &max_level);
}
// Driver Program to test above functions
int main()
{
struct node *root = newNode(12);
root->left = newNode(10);
root->right = newNode(30);
root->right->left = newNode(25);
root->right->right = newNode(40);
leftView(root);
return 0;
}
if(!bt->left()==NULL)
cout << bt->left()->getData() << "\t";
I'm preparing for a job interview. I was stuck at one of the binary tree questions:
How can we calculate the sum of the values present in all the nodes of a binary tree?
The elegant recursive solution (in pseudo-code):
def sum (node):
if node == NULL:
return 0
return node->value + sum (node->left) + sum (node->right)
then just use:
total = sum (root)
This correctly handles the case of a NULL root node.
And if you want to see it in action in C++, here's some code using that algorithm. First, the structure for a node and the sum function:
#include <iostream>
typedef struct sNode {
int value;
struct sNode *left;
struct sNode *right;
} tNode;
int sum (tNode *node) {
if (node == 0) return 0;
return node->value + sum (node->left) + sum (node->right);
}
Then the code below is a test harness code for inserting nodes:
static tNode *addNode (tNode *parent, char leftRight, int value) {
tNode *node = new tNode();
node->value = value;
node->left = 0;
node->right = 0;
if (parent != 0) {
if (leftRight == 'L') {
parent->left = node;
} else {
parent->right = node;
}
}
return node;
}
And, finally, the main function for constructing the following tree, one that covers all of the valid possibilities (empty node, node with two children, node with no children, node with one right child and node with one left child):
10
/ \
7 20
/ \
3 99
\
4
\
6
The code to construct that tree and report the sum at various points is shown here:
int main (void) {
// Empty tree first.
tNode *root = 0;
std::cout << sum (root) << '\n';
// Then a tree with single node (10).
root = addNode (0, ' ', 10);
std::cout << sum (root) << '\n';
// Then one with two subnodes (10, 7, 20).
addNode (root,'L',7);
addNode (root,'R',20);
std::cout << sum (root) << '\n';
// Then, finally, the full tree as per above.
addNode (root->left,'L',3);
addNode (root->left->left,'R',4);
addNode (root->left->left->right,'R',6);
addNode (root->right,'R',99);
std::cout << sum (root) << '\n';
return 0;
}
This outputs (the correct):
0
10
37
149
Traverse the tree in any order (pre, post, in). Instead of printing the node calculate the total.
void sum(Node* root, int& total)
{
if(root == NULL)
{
return;
}
sum(root->left, total);
total = total + root->value;
sum(root->right, total);
}
int main()
{
int total =0;
sum(root,total);
cout << total;
}
The same way you search the tree, or display each node, or any other tree-wide operation: visit the current node, visit the left sub-tree (recursively), and visit the right sub-tree (recursively).
Essentially, something like this:
int TreeNode::calculateSum() const
{
int sum = this->value;
if (this->left != NULL) sum += this->left ->calculateSum();
if (this->right != NULL) sum += this->right->calculateSum();
return sum;
}
Because of the if checks the recursion will eventually bottom out when it reaches nodes with no left or right children (leaf nodes).
While the STL has more complex and concise mechanisms for doing this, it's a very fast rode to productivity just to learn to use a manual loop over a container, something like:
Tree::value_type total = Tree::value_type();
for (Tree::const_iterator i = tree.begin(); i != tree.end(); ++i)
total += *i;
This assumes your binary tree is a STL::map, or if not you'll provide an iterator concept for your own implementation....
Use one of the Tree Traversal techniques(In-order, Pre-order, Post-order) to visit each node and store the sum in a variable.
You can find more details on tree traversal in this wiki
50
/ \
30 70
/ \ / \
20 40 60 80
returns:350
int Sum(struct node *root)
{
if(root->left == NULL && root->right== NULL)
return root->key;
int lvalue,rvalue;
lvalue=Sum(root->left);
rvalue=Sum(root->right);
return root->key+lvalue+rvalue;
}
public int sum(Node root){
if(root==null){
return 0;
}
if(root.left == null && root.right==null){
return root.key;
}
return sum(root.left)+sum(root.right)+root.key;
}