Level Order Tree Traversal
Level order traversal of a tree is breadth first traversal for the tree.
Level order traversal of the above tree is 1 2 3 4 5
METHOD 1 (Use function to print a given level)
Algorithm:
There are basically two functions in this method. One is to print all nodes at a given
level (printGivenLevel), and other is to print level order traversal of the tree
(printLevelorder). printLevelorder makes use of printGivenLevel to print nodes at all
levels one by one starting from root.
/*Function to print level order traversal of tree*/
printLevelorder(tree)
for d = 1 to height(tree)
printGivenLevel(tree, d);
/*Function to print all nodes at a given level*/
printGivenLevel(tree, level)
if tree is NULL then return;
if level is 1, then
print(tree->data);
else if level greater than 1, then
printGivenLevel(tree->left, level-1);
printGivenLevel(tree->right, level-1);
Implementation:
// Recursive CPP program for level
// order traversal of Binary 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, *right;
};
/* Function protoypes */
void printGivenLevel(node* root, int level);
int height(node* node);
node* newNode(int data);
/* Function to print level
order traversal a tree*/
void printLevelOrder(node* root)
{
int h = height(root);
int i;
for (i = 1; i <= h; i++)
printGivenLevel(root, i);
}
/* Print nodes at a given level */
void printGivenLevel(node* root, int level)
{
if (root == NULL)
return;
if (level == 1)
cout << root->data << " ";
else if (level > 1)
{
printGivenLevel(root->left, level-1);
printGivenLevel(root->right, level-1);
}
}
/* Compute the "height" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(node* node)
{
if (node == NULL)
return 0;
else
{
/* compute the height of each subtree */
int lheight = height(node->left);
int rheight = height(node->right);
/* use the larger one */
if (lheight > rheight)
return(lheight + 1);
else return(rheight + 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 << "Level Order traversal of binary tree is \n";
printLevelOrder(root);
return 0;
}
// This code is contributed by rathbhupendra
Output:
Level order traversal of binary tree is -
1 2 3 4 5
Time Complexity: O(n^2) in worst case. For a skewed tree, printGivenLevel() takes
O(n) time where n is the number of nodes in the skewed tree. So time complexity of
printLevelOrder() is O(n) + O(n-1) + O(n-2) + .. + O(1) which is O(n^2).
Diameter of a Binary Tree
The diameter of a tree (sometimes called the width) is the number of nodes on the
longest path between two end nodes. The diagram below shows two trees each with
diameter nine, the leaves that form the ends of a longest path are shaded (note that
there is more than one path in each tree of length nine, but no path longer than nine
nodes).
The diameter of a tree T is the largest of the following quantities:
* the diameter of T’s left subtree
* the diameter of T’s right subtree
* the longest path between leaves that goes through the root of T (this can be
computed from the heights of the subtrees of T)
Implementation:
C
Java
Python
filter_none
edit
play_arrow
brightness_5
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct node
{
int data;
struct node* left, *right;
};
/* function to create a new node of tree and returns pointer */
struct node* newNode(int data);
/* returns max of two integers */
int max(int a, int b);
/* function to Compute height of a tree. */
int height(struct node* node);
/* Function to get diameter of a binary tree */
int diameter(struct node * tree)
{
/* base case where tree is empty */
if (tree == NULL)
return 0;
/* get the height of left and right sub-trees */
int lheight = height(tree->left);
int rheight = height(tree->right);
/* get the diameter of left and right sub-trees */
int ldiameter = diameter(tree->left);
int rdiameter = diameter(tree->right);
/* Return max of following three
1) Diameter of left subtree
2) Diameter of right subtree
3) Height of left subtree + height of right subtree + 1 */
return max(lheight + rheight + 1, max(ldiameter, rdiameter));
}
/* UTILITY FUNCTIONS TO TEST diameter() FUNCTION */
/* The function Compute the "height" of a tree. Height is the
number f nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(struct node* node)
{
/* base case tree is empty */
if(node == NULL)
return 0;
/* If tree is not empty then height = 1 + max of left
height and right heights */
return 1 + max(height(node->left), height(node->right));
}
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newNode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
/* returns maximum of two integers */
int max(int a, int b)
{
return (a >= b)? a: b;
}
/* Driver program to test above functions*/
int main()
{
/* Constructed binary tree is
1
/ \
2 3
/ \
4 5
*/
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
printf("Diameter of the given binary tree is %d\n", diameter(root));
getchar();
return 0;
}
Time Complexity: O(n^2)
Output:
Diameter of the given binary tree is 4
Optimized implementation: The above implementation can be optimized by
calculating the height in the same recursion rather than calling a height() separately.
Thanks to Amar for suggesting this optimized version. This optimization reduces time
complexity to O(n).
/*The second parameter is to store the height of tree.
Initially, we need to pass a pointer to a location with value
as 0. So, function should be used as follows:
int height = 0;
struct node *root = SomeFunctionToMakeTree();
int diameter = diameterOpt(root, &height); */
int diameterOpt(struct node *root, int* height)
{
/* lh --> Height of left subtree
rh --> Height of right subtree */
int lh = 0, rh = 0;
/* ldiameter --> diameter of left subtree
rdiameter --> Diameter of right subtree */
int ldiameter = 0, rdiameter = 0;
if(root == NULL)
{
*height = 0;
return 0; /* diameter is also 0 */
}
/* Get the heights of left and right subtrees in lh and rh
And store the returned values in ldiameter and ldiameter */
ldiameter = diameterOpt(root->left, &lh);
rdiameter = diameterOpt(root->right, &rh);
/* Height of current node is max of heights of left and
right subtrees plus 1*/
*height = max(lh, rh) + 1;
return max(lh + rh + 1, max(ldiameter, rdiameter));
}
Time Complexity: O(n)
Output:
4
Input : 1
/ \
2 3
/ \
4 5
Output : 4
Input : 1
/ \
2 3
/ \ . \
4 5 . 6
Output : 5
We have discussed a solution in below post.
Diameter of a Binary Tree
In this post a new simple O(n) method is discussed. Diameter of a tree can be
calculated by only using the height function, because the diameter of a tree is
nothing but maximum value of (left_height + right_height + 1) for each node. So we
need to calculate this value (left_height + right_height + 1) for each node and update
the result. Time complexity – O(n)
// Simple C++ program to find diameter
// of a binary tree.
#include <bits/stdc++.h>
using namespace std;
/* Tree node structure used in the program */
struct Node {
int data;
Node* left, *right;
};
/* Function to find height of a tree */
int height(Node* root, int& ans)
{
if (root == NULL)
return 0;
int left_height = height(root->left, ans);
int right_height = height(root->right, ans);
// update the answer, because diameter of a
// tree is nothing but maximum value of
// (left_height + right_height + 1) for each node
ans = max(ans, 1 + left_height + right_height);
return 1 + max(left_height, right_height);
}
/* Computes the diameter of binary tree with given root. */
int diameter(Node* root)
{
if (root == NULL)
return 0;
int ans = INT_MIN; // This will store the final answer
int height_of_tree = height(root, ans);
return ans;
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return (node);
}
// Driver code
int main()
{
struct Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
printf("Diameter is %d\n", diameter(root));
return 0;
}
Output:
Diameter is 4
Lowest Common Ancestor in a Binary Tree | Set 1
Given a binary tree (not a binary search tree) and two values say n1 and n2, write a
program to find the least common ancestor.
Following is definition of LCA from Wikipedia:
Let T be a rooted tree. The lowest common ancestor between two nodes n1 and n2
is defined as the lowest node in T that has both n1 and n2 as descendants (where
we allow a node to be a descendant of itself).
The LCA of n1 and n2 in T is the shared ancestor of n1 and n2 that is located
farthest from the root. Computation of lowest common ancestors may be useful, for
instance, as part of a procedure for determining the distance between pairs of nodes
in a tree: the distance from n1 to n2 can be computed as the distance from the root
to n1, plus the distance from the root to n2, minus twice the distance from the root to
their lowest common ancestor. (Source Wiki)
Method 2 (Using Single Traversal)
The method 1 finds LCA in O(n) time, but requires three tree traversals plus extra
spaces for path arrays. If we assume that the keys n1 and n2 are present in Binary
Tree, we can find LCA using single traversal of Binary Tree and without extra
storage for path arrays.
The idea is to traverse the tree starting from root. If any of the given keys (n1 and n2)
matches with root, then root is LCA (assuming that both keys are present). If root
doesn’t match with any of the keys, we recur for left and right subtree. The node
which has one key present in its left subtree and the other key present in right
subtree is the LCA. If both keys lie in left subtree, then left subtree has LCA also,
otherwise LCA lies in right subtree.
C++
Java
Python
filter_none
edit
play_arrow
brightness_5
/* C++ Program to find LCA of n1 and n2 using one traversal of Binary Tree */
#include <iostream>
using namespace std;
// A Binary Tree Node
struct Node
{
struct Node *left, *right;
int key;
};
// Utility function to create a new tree Node
Node* newNode(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return temp;
}
// This function returns pointer to LCA of two given values n1 and n2.
// This function assumes that n1 and n2 are present in Binary Tree
struct Node *findLCA(struct Node* root, int n1, int n2)
{
// Base case
if (root == NULL) return NULL;
// If either n1 or n2 matches with root's key, report
// the presence by returning root (Note that if a key is
// ancestor of other, then the ancestor key becomes LCA
if (root->key == n1 || root->key == n2)
return root;
// Look for keys in left and right subtrees
Node *left_lca = findLCA(root->left, n1, n2);
Node *right_lca = findLCA(root->right, n1, n2);
// If both of the above calls return Non-NULL, then one key
// is present in once subtree and other is present in other,
// So this node is the LCA
if (left_lca && right_lca) return root;
// Otherwise check if left subtree or right subtree is LCA
return (left_lca != NULL)? left_lca: right_lca;
}
// Driver program to test above functions
int main()
{
// Let us create binary tree given in the above example
Node * root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->right->left = newNode(6);
root->right->right = newNode(7);
cout << "LCA(4, 5) = " << findLCA(root, 4, 5)->key;
cout << "nLCA(4, 6) = " << findLCA(root, 4, 6)->key;
cout << "nLCA(3, 4) = " << findLCA(root, 3, 4)->key;
cout << "nLCA(2, 4) = " << findLCA(root, 2, 4)->key;
return 0;
}
Output:
LCA(4, 5) = 2
LCA(4, 6) = 1
LCA(3, 4) = 1
LCA(2, 4) = 2
Thanks to Atul Singh for suggesting this solution.
Time Complexity: Time complexity of the above solution is O(n) as the method
does a simple tree traversal in bottom up fashion.
Note that the above method assumes that keys are present in Binary Tree. If one
key is present and other is absent, then it returns the present key as LCA (Ideally
should have returned NULL).
We can extend this method to handle all cases by passing two boolean variables v1
and v2. v1 is set as true when n1 is present in tree and v2 is set as true if n2 is
present in tree.
C++
Java
Python
C#
filter_none
edit
play_arrow
brightness_5
/* C++ program to find LCA of n1 and n2 using one traversal of Binary Tree.
It handles all cases even when n1 or n2 is not there in Binary Tree */
#include <iostream>
using namespace std;
// A Binary Tree Node
struct Node
{
struct Node *left, *right;
int key;
};
// Utility function to create a new tree Node
Node* newNode(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return temp;
}
// This function returns pointer to LCA of two given values n1 and n2.
// v1 is set as true by this function if n1 is found
// v2 is set as true by this function if n2 is found
struct Node *findLCAUtil(struct Node* root, int n1, int n2, bool &v1, bool &v2)
{
// Base case
if (root == NULL) return NULL;
// If either n1 or n2 matches with root's key, report the presence
// by setting v1 or v2 as true and return root (Note that if a key
// is ancestor of other, then the ancestor key becomes LCA)
if (root->key == n1)
{
v1 = true;
return root;
}
if (root->key == n2)
{
v2 = true;
return root;
}
// Look for keys in left and right subtrees
Node *left_lca = findLCAUtil(root->left, n1, n2, v1, v2);
Node *right_lca = findLCAUtil(root->right, n1, n2, v1, v2);
// If both of the above calls return Non-NULL, then one key
// is present in once subtree and other is present in other,
// So this node is the LCA
if (left_lca && right_lca) return root;
// Otherwise check if left subtree or right subtree is LCA
return (left_lca != NULL)? left_lca: right_lca;
}
// Returns true if key k is present in tree rooted with root
bool find(Node *root, int k)
{
// Base Case
if (root == NULL)
return false;
// If key is present at root, or in left subtree or right subtree,
// return true;
if (root->key == k || find(root->left, k) || find(root->right, k))
return true;
// Else return false
return false;
}
// This function returns LCA of n1 and n2 only if both n1 and n2 are present
// in tree, otherwise returns NULL;
Node *findLCA(Node *root, int n1, int n2)
{
// Initialize n1 and n2 as not visited
bool v1 = false, v2 = false;
// Find lca of n1 and n2 using the technique discussed above
Node *lca = findLCAUtil(root, n1, n2, v1, v2);
// Return LCA only if both n1 and n2 are present in tree
if (v1 && v2 || v1 && find(lca, n2) || v2 && find(lca, n1))
return lca;
// Else return NULL
return NULL;
}
// Driver program to test above functions
int main()
{
// Let us create binary tree given in the above example
Node * root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->right->left = newNode(6);
root->right->right = newNode(7);
Node *lca = findLCA(root, 4, 5);
if (lca != NULL)
cout << "LCA(4, 5) = " << lca->key;
else
cout << "Keys are not present ";
lca = findLCA(root, 4, 10);
if (lca != NULL)
cout << "nLCA(4, 10) = " << lca->key;
else
cout << "nKeys are not present ";
return 0;
}
Output:
LCA(4, 5) = 2
Keys are not present
Convert a given tree to its Sum Tree
Given a Binary Tree where each node has positive and negative values. Convert this
to a tree where each node contains the sum of the left and right sub trees in the
original tree. The values of leaf nodes are changed to 0.
For example, the following tree
10
/ \
-2 6
/ \ / \
8 -4 7 5
should be changed to
20(4-2+12+6)
/ \
4(8-4) 12(7+5)
/ \ / \
0 0 0 0
Solution:
Do a traversal of the given tree. In the traversal, store the old value of the current
node, recursively call for left and right subtrees and change the value of current node
as sum of the values returned by the recursive calls. Finally return the sum of new
value and value (which is sum of values in the subtree rooted with this node).
#include<stdio.h>
/* A tree node structure */
struct node
{
int data;
struct node *left;
struct node *right;
};
// Convert a given tree to a tree where every node contains sum of values of
// nodes in left and right subtrees in the original tree
int toSumTree(struct node *node)
{
// Base case
if(node == NULL)
return 0;
// Store the old value
int old_val = node->data;
// Recursively call for left and right subtrees and store the sum as
// new value of this node
node->data = toSumTree(node->left) + toSumTree(node->right);
// Return the sum of values of nodes in left and right subtrees and
// old_value of this node
return node->data + old_val;
}
// A utility function to print inorder traversal of a Binary Tree
void printInorder(struct node* node)
{
if (node == NULL)
return;
printInorder(node->left);
printf("%d ", node->data);
printInorder(node->right);
}
/* Utility function to create a new Binary Tree node */
struct node* newNode(int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
/* Driver function to test above functions */
int main()
{
struct node *root = NULL;
int x;
/* Constructing tree given in the above figure */
root = newNode(10);
root->left = newNode(-2);
root->right = newNode(6);
root->left->left = newNode(8);
root->left->right = newNode(-4);
root->right->left = newNode(7);
root->right->right = newNode(5);
toSumTree(root);
// Print inorder traversal of the converted tree to test result of toSumTree()
printf("Inorder Traversal of the resultant tree is: \n");
printInorder(root);
getchar();
return 0;
}
Output:
Inorder Traversal of the resultant tree is:
0 4 0 20 0 12 0
Time Complexity: The solution involves a simple traversal of the given tree. So the
time complexity is O(n) where n is the number of nodes in the given Binary Tree.
rint Left View of a Binary Tree
Given a Binary Tree, print left view of it. Left view of a Binary Tree is set of nodes
visible when tree is visited from left side.
Examples:
Input :
1
/ \
2 3
/ \ \
4 5 6
Output : 1 2 4
Input :
1
/ \
2 3
\
4
\
5
\
6
Output :1 2 4 5 6
Recommended: Please solve it on “PRACTICE” first, before moving on to
the solution.
The left view contains all nodes that are first nodes in their levels. A simple solution
is to do level order traversal and print the first node in every level.
The problem can also be solved using simple recursive traversal. We can keep
track of level of a node by passing a parameter to all recursive calls. The idea is to
keep track of maximum level also. Whenever we see a node whose level is more
than maximum level so far, we print the node because this is the first node in its level
(Note that we traverse the left subtree before right subtree). Following is the
implementation-
// C program to print left view of Binary Tree
#include<stdio.h>
#include<stdlib.h>
struct node
int data;
struct node *left, *right;
};
// A utility function to create a new Binary Tree node
struct node *newNode(int item)
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}
// Recursive function to print left view of a binary tree.
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;
Output:
12 10 25
Time Complexity: The function does a simple traversal of the tree, so the
complexity is O(n).