Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 56

Binary Tree Data Structure

A tree whose elements have at most 2 children is called a binary tree. Since each
element in a binary tree can have only 2 children, we typically name them the left
and right child.

A Binary Tree node contains following parts.


1. Data
2. Pointer to left child
3. Pointer to right child

Binary Tree | Set 1 (Introduction)


Trees: Unlike Arrays, Linked Lists, Stack and queues, which are linear data structures,
trees are hierarchical data structures.
Tree Vocabulary: The topmost node is called root of the tree. The elements that are
directly under an element are called its children. The element directly above
something is called its parent. For example, ‘a’ is a child of ‘f’, and ‘f’ is the parent of
‘a’. Finally, elements with no children are called leaves.
tree
----
j <-- root
/ \
f k
/ \ \
a h z <-- leaves
Why Trees?
1. One reason to use trees might be because you want to store information that
naturally forms a hierarchy. For example, the file system on a computer:

file system
-----------
/ <-- root
/ \
... home
/ \
ugrad course
/ / | \
... cs101 cs112 cs113
2. Trees (with some ordering e.g., BST) provide moderate access/search (quicker
than Linked List and slower than arrays).
3. Trees provide moderate insertion/deletion (quicker than Arrays and slower than
Unordered Linked Lists).
4. Like Linked Lists and unlike Arrays, Trees don’t have an upper limit on number of
nodes as nodes are linked using pointers.
Main applications of trees include:
1. Manipulate hierarchical data.
2. Make information easy to search (see tree traversal).
3. Manipulate sorted lists of data.
4. As a workflow for compositing digital images for visual effects.
5. Router algorithms
6. Form of a multi-stage decision-making (see business chess).
Binary Tree: A tree whose elements have at most 2 children is called a binary tree.
Since each element in a binary tree can have only 2 children, we typically name them
the left and right child.
Binary Tree Representation in C: A tree is represented by a pointer to the topmost
node in tree. If the tree is empty, then value of root is NULL.
A Tree node contains following parts.
1. Data
2. Pointer to left child
3. Pointer to right child
/* Class containing left and right child of current
   node and key value*/
class Node
{
    int key;
    Node left, right;
  
    public Node(int item)
    {
        key = item;
        left = right = null;
    }
}
  
// A Java program to introduce Binary Tree
class BinaryTree
{
    // Root of Binary Tree
    Node root;
  
    // Constructors
    BinaryTree(int key)
    {
        root = new Node(key);
    }
  
    BinaryTree()
    {
        root = null;
    }
  
    public static void main(String[] args)
    {
        BinaryTree tree = new BinaryTree();
  
        /*create root*/
        tree.root = new Node(1);
  
        /* following is the tree after above statement
  
              1
            /   \
          null  null     */
  
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
  
        /* 2 and 3 become left and right children of 1
               1
             /   \
            2      3
          /    \    /  \
        null null null null  */
  
  
        tree.root.left.left = new Node(4);
        /* 4 becomes left child of 2
                    1
                /       \
               2          3
             /   \       /  \
            4    null  null  null
           /   \
          null null
         */
    }
}
Summary: Tree is a hierarchical data structure. Main uses of trees include
maintaining hierarchical data, providing moderate access and insert/delete
operations. Binary trees are special cases of tree where every node has at most two
children.

Binary Tree | Set 2 (Properties)


We have discussed Introduction to Binary Tree in set 1. In this post, properties of
binary are discussed.

1) The maximum number of nodes at level ‘l’ of a binary tree is 2l-1.


Here level is number of nodes on path from root to the node (including root and
node). Level of root is 1.
This can be proved by induction.
For root, l = 1, number of nodes = 21-1 = 1
Assume that maximum number of nodes on level l is 2l-1
Since in Binary tree every node has at most 2 children, next level would have twice
nodes, i.e. 2 * 2l-1
 
2) Maximum number of nodes in a binary tree of height ‘h’ is 2h – 1.
Here height of a tree is maximum number of nodes on root to leaf path. Height of a
tree with single node is considered as 1.
This result can be derived from point 2 above. A tree has maximum nodes if all levels
have maximum nodes. So maximum number of nodes in a binary tree of height h is 1
+ 2 + 4 + .. + 2h-1. This is a simple geometric series with h terms and sum of this series
is 2h – 1.
In some books, height of the root is considered as 0. In this convention, the above
formula becomes 2h+1 – 1

 
3) In a Binary Tree with N nodes, minimum possible height or minimum number of
levels is  ? Log2(N+1) ?  
This can be directly derived from point 2 above. If we consider the convention where
height of a leaf node is considered as 0, then above formula for minimum possible
height becomes   ? Log2(N+1) ? – 1
 
4) A Binary Tree with L leaves has at least   ? Log2L ? + 1   levels
A Binary tree has maximum number of leaves (and minimum number of levels) when
all levels are fully filled. Let all leaves be at level l, then below is true for number of
leaves L.
L <= 2l-1 [From Point 1]
l = ? Log2L ? + 1
where l is the minimum number of levels.
 
5) In Binary tree where every node has 0 or 2 children, number of leaf nodes is
always one more than nodes with two children.
L=T+1
Where L = Number of leaf nodes
T = Number of internal nodes with two children

Binary Tree | Set 3 (Types of Binary


Tree)
We have discussed Introduction to Binary Tree in set 1 and Properties of Binary Tree
in Set 2. In this post, common types of binary is discussed.
Following are common types of Binary Trees.
Full Binary Tree A Binary Tree is full if every node has 0 or 2 children. Following are
examples of a full binary tree. We can also say a full binary tree is a binary tree in
which all nodes except leaves have two children.

18
/ \
15 30
/ \ / \
40 50 100 40

18
/ \
15 20
/ \
40 50
/ \
30 50

18
/ \
40 30
/ \
100 40

In a Full Binary, number of leaf nodes is number of internal nodes plus 1


       L = I + 1
Where L = Number of leaf nodes, I = Number of internal nodes
See Handshaking Lemma and Tree for proof.

Complete Binary Tree: A Binary Tree is complete Binary Tree if all levels are
completely filled except possibly the last level and the last level has all keys as left as
possible
Following are examples of Complete Binary Trees
18
/ \
15 30
/ \ / \
40 50 100 40

18
/ \
15 30
/ \ / \
40 50 100 40
/ \ /
8 7 9
Practical example of Complete Binary Tree is Binary Heap.

Perfect Binary Tree A Binary tree is Perfect Binary Tree in which all internal nodes
have two children and all leaves are at the same level.
Following are examples of Perfect Binary Trees.
18
/ \
15 30
/ \ / \
40 50 100 40

18
/ \
15 30
A Perfect Binary Tree of height h (where height is the number of nodes on the path
from the root to leaf) has 2h – 1 node.
Example of a Perfect binary tree is ancestors in the family. Keep a person at root,
parents as children, parents of parents as their children.

Balanced Binary Tree


A binary tree is balanced if the height of the tree is O(Log n) where n is the number
of nodes. For Example, AVL tree maintains O(Log n) height by making sure that the
difference between heights of left and right subtrees is atmost 1. Red-Black trees
maintain O(Log n) height by making sure that the number of Black nodes on every
root to leaf paths are same and there are no adjacent red nodes. Balanced Binary
Search trees are performance wise good as they provide O(log n) time for search,
insert and delete.

A degenerate (or pathological) tree A Tree where every internal node has one child.
Such trees are performance-wise same as linked list.
10
/
20
\
30
\
40

Handshaking Lemma and Interesting Tree


Properties
What is Handshaking Lemma?
Handshaking lemma is about undirected graph. In every finite undirected graph
number of vertices with odd degree is always even. The handshaking lemma is a
consequence of the degree sum formula (also sometimes called the handshaking
lemma)

How is Handshaking Lemma useful in Tree Data structure?


Following are some interesting facts that can be proved using Handshaking lemma.
1) In a k-ary tree where every node has either 0 or k children, following property is
always true.

L = (k - 1)*I + 1
Where L = Number of leaf nodes
I = Number of internal nodes
Proof:
Proof can be divided in two cases.
Case 1 (Root is Leaf):There is only one node in tree. The above formula is true for
single node as L = 1, I = 0.
Case 2 (Root is Internal Node): For trees with more than 1 nodes, root is always
internal node. The above formula can be proved using Handshaking Lemma for this
case. A tree is an undirected acyclic graph.
Total number of edges in Tree is number of nodes minus 1, i.e., |E| = L + I – 1.
All internal nodes except root in the given type of tree have degree k + 1. Root has
degree k. All leaves have degree 1. Applying the Handshaking lemma to such trees,
we get following relation.
Sum of all degrees = 2 * (Sum of Edges)

Sum of degrees of leaves +


Sum of degrees for Internal Node except root +
Root's degree = 2 * (No. of nodes - 1)

Putting values of above terms,


L + (I-1)*(k+1) + k = 2 * (L + I - 1)
L + k*I - k + I -1 + k = 2*L + 2I - 2
L + K*I + I - 1 = 2*L + 2*I - 2
K*I + 1 - I = L
(K-1)*I + 1 = L
So the above property is proved using Handshaking Lemma, let us discuss one more
interesting property.
Alternate Proof: (Without using Handshaking Theorem)
Since there are I internal nodes, each having K children, therefore total children in
the tree = K * I.
There are I-1 internal nodes which are children of some other node (root has been
excluded hence one less than the total number of internal nodes)
That is, out of these K*I children, I-1 are internal nodes and therefore the rest (K*I –
(I-1)) are leaves.
Hence L = (K-1)*I + 1.
 
 
 
2) In Binary tree, number of leaf nodes is always one more than nodes with two
children.

L=T+1
Where L = Number of leaf nodes
T = Number of internal nodes with two children
Proof:
Let number of nodes with 2 children be T. Proof can be divided in three cases.
 
Case 1: There is only one node, the relationship holds
as T = 0, L = 1.
 
Case 2: Root has two children, i.e., degree of root is 2.
Sum of degrees of nodes with two children except root +
Sum of degrees of nodes with one child +
Sum of degrees of leaves + Root's degree = 2 * (No. of Nodes - 1)

Putting values of above terms,


(T-1)*3 + S*2 + L + 2 = (S + T + L - 1)*2

Cancelling 2S from both sides.


(T-1)*3 + L + 2 = (T + L - 1)*2
T-1=L-2
T=L-1
 
Case 3: Root has one child, i.e., degree of root is 1.
Sum of degrees of nodes with two children +
Sum of degrees of nodes with one child except root +
Sum of degrees of leaves + Root's degree = 2 * (No. of Nodes - 1)

Putting values of above terms,


T*3 + (S-1)*2 + L + 1 = (S + T + L - 1)*2

Cancelling 2S from both sides.


3*T + L -1 = 2*T + 2*L - 2
T-1=L-2
T=L-1
Therefore, in all three cases, we get T = L-1.

Enumeration of Binary Trees


A Binary Tree is labeled if every node is assigned a label and a Binary Tree is
unlabeled if nodes are not assigned any label.
Below two are considered same unlabeled trees
o o
/ \ / \
o o o o

Below two are considered different labeled trees


A C
/ \ / \
B C A B
How many different Unlabeled Binary Trees can be there with n nodes?
For n = 1, there is only one tree
o

For n = 2, there are two trees


o o
/ \
o o

For n = 3, there are five trees


o o o o o
/ \ / \ / \
o o o o o o
/ \ \ /
o o o o
The idea is to consider all possible pair of counts for nodes in left and right subtrees
and multiply the counts for a particular pair. Finally add results of all pairs.

For example, let T(n) be count for n nodes.


T(0) = 1 [There is only 1 empty tree]
T(1) = 1
T(2) = 2

T(3) = T(0)*T(2) + T(1)*T(1) + T(2)*T(0) = 1*2 + 1*1 + 2*1 = 5

T(4) = T(0)*T(3) + T(1)*T(2) + T(2)*T(1) + T(3)*T(0)


= 1*5 + 1*2 + 2*1 + 5*1
= 14
The above pattern basically represents n’th Catalan Numbers. First few catalan
numbers are 1 1 2 5 14 42 132 429 1430 4862,…

Here,
T(i-1) represents number of nodes on the left-sub-tree
T(n−i-1) represents number of nodes on the right-sub-tree
n’th Catalan Number can also be evaluated using direct formula.
T(n) = (2n)! / (n+1)!n!
Number of Binary Search Trees (BST) with n nodes is also same as number of
unlabeled trees. The reason for this is simple, in BST also we can make any key as
root, If root is i’th key in sorted order, then i-1 keys can go on one side and (n-i) keys
can go on other side.
How many labeled Binary Trees can be there with n nodes?
To count labeled trees, we can use above count for unlabeled trees. The idea is
simple, every unlabeled tree with n nodes can create n! different labeled trees by
assigning different permutations of labels to all nodes.
Therefore,
Number of Labeled Tees = (Number of unlabeled trees) * n!
= [(2n)! / (n+1)!n!] × n!
For example for n = 3, there are 5 * 3! = 5*6 = 30 different labeled trees
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above

Insertion in a Binary Tree in level


order
Given a binary tree and a key, insert the key into the binary tree at first position
available in level order.

The idea is to do iterative level order traversal of the given tree using queue. If we
find a node whose left child is empty, we make new key as left child of the node. Else
if we find a node whose right child is empty, we make new key as right child. We
keep traversing the tree until we find a node whose either left or right is empty.
// Java program to insert element in binary tree
import java.util.LinkedList;
import java.util.Queue;
public class GFG {
       
    /* A binary tree node has key, pointer to 
    left child and a pointer to right child */
    static class Node {
        int key;
        Node left, right;
          
        // constructor
        Node(int key){
            this.key = key;
            left = null;
            right = null;
        }
    }
    static Node root;
    static Node temp = root;
      
    /* Inorder traversal of a binary tree*/
    static void inorder(Node temp)
    {
        if (temp == null)
            return;
       
        inorder(temp.left);
        System.out.print(temp.key+" ");
        inorder(temp.right);
    }
       
    /*function to insert element in binary tree */
    static void insert(Node temp, int key)
    {
        Queue<Node> q = new LinkedList<Node>();
        q.add(temp);
       
        // Do level order traversal until we find
        // an empty place. 
        while (!q.isEmpty()) {
            temp = q.peek();
            q.remove();
       
            if (temp.left == null) {
                temp.left = new Node(key);
                break;
            } else
                q.add(temp.left);
       
            if (temp.right == null) {
                temp.right = new Node(key);
                break;
            } else
                q.add(temp.right);
        }
    }
       
    // Driver code
    public static void main(String args[])
    {
        root = new Node(10);
        root.left = new Node(11);
        root.left.left = new Node(7);
        root.right = new Node(9);
        root.right.left = new Node(15);
        root.right.right = new Node(8);
       
        System.out.print( "Inorder traversal before insertion:");
        inorder(root);
       
        int key = 12;
        insert(root, key);
       
        System.out.print("\nInorder traversal after insertion:");
        inorder(root);
    }
}
Output:
Inorder traversal before insertion: 7 11 10 15 9 8
Inorder traversal after insertion: 7 11 12 10 15 9 8

BFS vs DFS for Binary Tree


What are BFS and DFS for Binary Tree?
A Tree is typically traversed in two ways:
 Breadth First Traversal (Or Level Order Traversal)
 Depth First Traversals
 Inorder Traversal (Left-Root-Right)
 Preorder Traversal (Root-Left-Right)
 Postorder Traversal (Left-Right-Root)

BFS and DFSs of above Tree

Breadth First Traversal : 1 2 3 4 5

Depth First Traversals:


Preorder Traversal : 1 2 4 5 3
Inorder Traversal : 4 2 5 1 3
Postorder Traversal : 4 5 2 3 1
Why do we care?
There are many tree questions that can be solved using any of the above four
traversals. Examples of such questions are size, maximum, minimum, print left view,
etc.

Is there any difference in terms of Time Complexity?


All four traversals require O(n) time as they visit every node exactly once.
Is there any difference in terms of Extra Space?
There is difference in terms of extra space required.
1. Extra Space required for Level Order Traversal is O(w) where w is maximum
width of Binary Tree. In level order traversal, queue one by one stores nodes of
different level.
2. Extra Space required for Depth First Traversals is O(h) where h is maximum
height of Binary Tree. In Depth First Traversals, stack (or function call stack)
stores all ancestors of a node.
Maximum Width of a Binary Tree at depth (or height) h can be 2 h where h starts
from 0. So the maximum number of nodes can be at the last level. And worst case
occurs when Binary Tree is a perfect Binary Tree with numbers of nodes like 1, 3, 7,
15, …etc. In worst case, value of 2h is Ceil(n/2).
Height for a Balanced Binary Tree is O(Log n). Worst case occurs for skewed tree and
worst case height becomes O(n).
So in worst case extra space required is O(n) for both. But worst cases occur for
different types of trees.
It is evident from above points that extra space required for Level order traversal is
likely to be more when tree is more balanced and extra space for Depth First
Traversal is likely to be more when tree is less balanced.
How to Pick One?
1. Extra Space can be one factor (Explained above)
2. Depth First Traversals are typically recursive and recursive code requires
function call overheads.
3. The most important points is, BFS starts visiting nodes from root while DFS
starts visiting nodes from leaves. So if our problem is to search something that
is more likely to closer to root, we would prefer BFS. And if the target node is
close to a leaf, we would prefer DFS.

Binary Tree (Array implementation)


Talking about representation, trees can be represented in two way:
1) Dynamic Node Representation (Linked Representation).
2) Array Representation (Sequential Representation).
We are going to talk about the sequential representation of the trees.
To represent tree using an array, numbering of nodes can start either from 0–(n-1)
or 1– n.
A(0)
/ \
B(1) C(2)
/ \ \
D(3) E(4) F(6)
OR,
A(1)
/ \
B(2) C(3)
/ \ \
D(4) E(5) F(7)
For first case(0—n-1),
if (say)father=p;
then left_son=(2*p)+1;
and right_son=(2*p)+2;

For second case(1—n),


if (say)father=p;
then left_son=(2*p);
and right_son=(2*p)+1;
where father, left_son and right_son are the values of indices of the array.
// JAVA implementation of tree using array
// numbering starting from 0 to n-1.
import java.util.*;
import java.lang.*;
import java.io.*;
  
class Tree {
    public static void main(String[] args)
    {
        Array_imp obj = new Array_imp();
        obj.Root("A");
        // obj.set_Left("B", 0);
        obj.set_Right("C", 0);
        obj.set_Left("D", 1);
        obj.set_Right("E", 1);
        obj.set_Left("F", 2);
        obj.print_Tree();
    }
}
  
class Array_imp {
    static int root = 0;
    static String[] str = new String[10];
  
    /*create root*/
    public void Root(String key)
    {
        str[0] = key;
    }
  
    /*create left son of root*/
    public void set_Left(String key, int root)
    {
        int t = (root * 2) + 1;
  
        if (str[root] == null) {
            System.out.printf("Can't set child at %d, no parent found\n",
t);
        }
        else {
            str[t] = key;
        }
    }
  
    /*create right son of root*/
    public void set_Right(String key, int root)
    {
        int t = (root * 2) + 2;
  
        if (str[root] == null) {
            System.out.printf("Can't set child at %d, no parent found\n",
t);
        }
        else {
            str[t] = key;
        }
    }
  
    public void print_Tree()
    {
        for (int i = 0; i < 10; i++) {
            if (str[i] != null)
                System.out.print(str[i]);
            else
                System.out.print("-");
        }
    }
}
Output:
Can't set child at 3, no parent found
Can't set child at 4, no parent found
A-C--F----
Note – Please refer this if you want to construct tree from the given parent array.

Applications of tree data structure

Why Tree?
Unlike Array and Linked List, which are linear data structures, tree is hierarchical (or
non-linear) data structure.
1. One reason to use trees might be because you want to store information that
naturally forms a hierarchy. For example, the file system on a computer:
file system
———–
2.
/ <-- root
/ \
... home
/ \
ugrad course
/ / | \
... cs101 cs112 cs113
3.
4. If we organize keys in form of a tree (with some ordering e.g., BST), we can
search for a given key in moderate time (quicker than Linked List and slower
than arrays). Self-balancing search trees like AVL and Red-Black
trees guarantee an upper bound of O(Logn) for search.
5. We can insert/delete keys in moderate time (quicker than Arrays and slower
than Unordered Linked Lists). Self-balancing search trees like AVL and Red-
Black trees guarantee an upper bound of O(Logn) for insertion/deletion.
6. Like Linked Lists and unlike Arrays, Pointer implementation of trees don’t
have an upper limit on number of nodes as nodes are linked using pointers.
Other Applications :

1. Heap is a tree data structure which is implemented using arrays and used to
implement priority queues.
2. B-Tree and B+ Tree : They are used to implement indexing in databases.
3. Syntax Tree: Used in Compilers.
4. K-D Tree: A space partitioning tree used to organize points in K dimensional
space.
5. Trie : Used to implement dictionaries with prefix lookup.
6. Suffix Tree : For quick pattern searching in a fixed text.
Traversals :

Tree Traversals (Inorder, Preorder and


Postorder)
Unlike linear data structures (Array, Linked List, Queues, Stacks, etc) which have only
one logical way to traverse them, trees can be traversed in different ways. Following
are the generally used ways for traversing trees.

Example Tree

Depth First Traversals:


(a) Inorder (Left, Root, Right) : 4 2 5 1 3
(b) Preorder (Root, Left, Right) : 1 2 4 5 3
(c) Postorder (Left, Right, Root) : 4 5 2 3 1
Breadth First or Level Order Traversal : 1 2 3 4 5
Please see this post for Breadth First Traversal.

Inorder Traversal (Practice):


Algorithm Inorder(tree)
1. Traverse the left subtree, i.e., call Inorder(left-subtree)
2. Visit the root.
3. Traverse the right subtree, i.e., call Inorder(right-subtree)
Uses of Inorder
In case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing
order. To get nodes of BST in non-increasing order, a variation of Inorder traversal
where Inorder traversal s reversed can be used.
Example: Inorder traversal for the above-given figure is 4 2 5 1 3.

Preorder Traversal (Practice):


Algorithm Preorder(tree)
1. Visit the root.
2. Traverse the left subtree, i.e., call Preorder(left-subtree)
3. Traverse the right subtree, i.e., call Preorder(right-subtree)
Uses of Preorder
Preorder traversal is used to create a copy of the tree. Preorder traversal is also used
to get prefix expression on of an expression tree. Please
see http://en.wikipedia.org/wiki/Polish_notation to know why prefix expressions are
useful.
Example: Preorder traversal for the above given figure is 1 2 4 5 3.

Postorder Traversal (Practice):


Algorithm Postorder(tree)
1. Traverse the left subtree, i.e., call Postorder(left-subtree)
2. Traverse the right subtree, i.e., call Postorder(right-subtree)
3. Visit the root.
Uses of Postorder
Postorder traversal is used to delete the tree. Please see the question for deletion of
tree for details. Postorder traversal is also useful to get the postfix expression of an
expression tree. Please see http://en.wikipedia.org/wiki/Reverse_Polish_notation to
for the usage of postfix expression.
Example: Postorder traversal for the above given figure is 4 5 2 3 1.

// Java program for different tree traversals


  
/* Class containing left and right child of current
   node and key value*/
class Node
{
    int key;
    Node left, right;
  
    public Node(int item)
    {
        key = item;
        left = right = null;
    }
}
  
class BinaryTree
{
    // Root of Binary Tree
    Node root;
  
    BinaryTree()
    {
        root = null;
    }
  
    /* Given a binary tree, print its nodes according to the
      "bottom-up" postorder traversal. */
    void printPostorder(Node node)
    {
        if (node == null)
            return;
  
        // first recur on left subtree
        printPostorder(node.left);
  
        // then recur on right subtree
        printPostorder(node.right);
  
        // now deal with the node
        System.out.print(node.key + " ");
    }
  
    /* Given a binary tree, print its nodes in inorder*/
    void printInorder(Node node)
    {
        if (node == null)
            return;
  
        /* first recur on left child */
        printInorder(node.left);
  
        /* then print the data of node */
        System.out.print(node.key + " ");
  
        /* now recur on right child */
        printInorder(node.right);
    }
  
    /* Given a binary tree, print its nodes in preorder*/
    void printPreorder(Node node)
    {
        if (node == null)
            return;
  
        /* first print data of node */
        System.out.print(node.key + " ");
  
        /* then recur on left sutree */
        printPreorder(node.left);
  
        /* now recur on right subtree */
        printPreorder(node.right);
    }
  
    // Wrappers over above recursive functions
    void printPostorder()  {     printPostorder(root);  }
    void printInorder()    {     printInorder(root);   }
    void printPreorder()   {     printPreorder(root);  }
  
    // Driver method
    public static void main(String[] args)
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
  
        System.out.println("Preorder traversal of binary tree is ");
        tree.printPreorder();
  
        System.out.println("\nInorder traversal of binary tree is ");
        tree.printInorder();
  
        System.out.println("\nPostorder traversal of binary tree is ");
        tree.printPostorder();
    }
}
Output:
Preorder traversal of binary tree is
12453
Inorder traversal of binary tree is
42513
Postorder traversal of binary tree is
45231
Inorder Tree Traversal without
Recursion
Using Stack is the obvious way to traverse tree without recursion. Below is an
algorithm for traversing binary tree using stack. See this for step wise step execution
of the algorithm.
1) Create an empty stack S.
2) Initialize current node as root
3) Push the current node to S and set current = current->left until current is NULL
4) If current is NULL and stack is not empty then
a) Pop the top item from stack.
b) Print the popped item, set current = popped_item->right
c) Go to step 3.
5) If current is NULL and stack is empty then we are done.
Let us consider the below tree for example

1
/ \
2 3
/ \
4 5

Step 1 Creates an empty stack: S = NULL

Step 2 sets current as address of root: current -> 1

Step 3 Pushes the current node and set current = current->left until current is NULL
current -> 1
push 1: Stack S -> 1
current -> 2
push 2: Stack S -> 2, 1
current -> 4
push 4: Stack S -> 4, 2, 1
current = NULL
Step 4 pops from S
a) Pop 4: Stack S -> 2, 1
b) print "4"
c) current = NULL /*right of 4 */ and go to step 3
Since current is NULL step 3 doesn't do anything.

Step 4 pops again.


a) Pop 2: Stack S -> 1
b) print "2"
c) current -> 5/*right of 2 */ and go to step 3

Step 3 pushes 5 to stack and makes current NULL


Stack S -> 5, 1
current = NULL

Step 4 pops from S


a) Pop 5: Stack S -> 1
b) print "5"
c) current = NULL /*right of 5 */ and go to step 3
Since current is NULL step 3 doesn't do anything

Step 4 pops again.


a) Pop 1: Stack S -> NULL
b) print "1"
c) current -> 3 /*right of 5 */

Step 3 pushes 3 to stack and makes current NULL


Stack S -> 3
current = NULL

Step 4 pops from S


a) Pop 3: Stack S -> NULL
b) print "3"
c) current = NULL /*right of 3 */

Traversal is done now as stack S is empty and current is NULL.


// non-recursive java program for inorder traversal
import java.util.Stack;
  
/* Class containing left and right child of
current node and key value*/
class Node
{
    int data;
    Node left, right;
  
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
  
/* Class to print the inorder traversal */
class BinaryTree
{
    Node root;
    void inorder()
    {
        if (root == null)
            return;
  
  
        Stack<Node> s = new Stack<Node>();
        Node curr = root;
  
        // traverse the tree
        while (curr != null || s.size() > 0)
        {
  
            /* Reach the left most Node of the
            curr Node */
            while (curr !=  null)
            {
                /* place pointer to a tree node on
                   the stack before traversing
                  the node's left subtree */
                s.push(curr);
                curr = curr.left;
            }
  
            /* Current must be NULL at this point */
            curr = s.pop();
  
            System.out.print(curr.data + " ");
  
            /* we have visited the node and its
               left subtree.  Now, it's right
               subtree's turn */
            curr = curr.right;
        }
    }
  
    public static void main(String args[])
    {
  
        /* creating a binary tree and entering
        the nodes */
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
        tree.inorder();
    }
}

Output:

42513
Time Complexity: O(n)

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 Java program for level order traversal of Binary Tree
  
/* Class containing left and right child of current 
   node and key value*/
class Node
{
    int data;
    Node left, right;
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
  
class BinaryTree
{
    // Root of the Binary Tree
    Node root;
  
    public BinaryTree()
    {
        root = null;
    }
  
    /* function to print level order traversal of tree*/
    void printLevelOrder()
    {
        int h = height(root);
        int i;
        for (i=1; i<=h; i++)
            printGivenLevel(root, i);
    }
  
    /* 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 root)
    {
        if (root == null)
           return 0;
        else
        {
            /* compute  height of each subtree */
            int lheight = height(root.left);
            int rheight = height(root.right);
              
            /* use the larger one */
            if (lheight > rheight)
                return(lheight+1);
            else return(rheight+1); 
        }
    }
  
    /* Print nodes at the given level */
    void printGivenLevel (Node root ,int level)
    {
        if (root == null)
            return;
        if (level == 1)
            System.out.print(root.data + " ");
        else if (level > 1)
        {
            printGivenLevel(root.left, level-1);
            printGivenLevel(root.right, level-1);
        }
    }
      
    /* Driver program to test above functions */
    public static void main(String args[])
    {
       BinaryTree tree = new BinaryTree();
       tree.root= new Node(1);
       tree.root.left= new Node(2);
       tree.root.right= new Node(3);
       tree.root.left.left= new Node(4);
       tree.root.left.right= new Node(5);
         
       System.out.println("Level order traversal of binary tree is ");
       tree.printLevelOrder();
    }
}
Output:
Level order traversal of binary tree is -
12345
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).

METHOD 2 (Use Queue)


Algorithm:
For each node, first the node is visited and then it’s child nodes are put in a FIFO
queue.
printLevelorder(tree)
1) Create an empty queue q
2) temp_node = root /*start from root*/
3) Loop while temp_node is not NULL
a) print temp_node->data.
b) Enqueue temp_node’s children (first left then right children) to q
c) Dequeue a node from q and assign it’s value to temp_node
Implementation:
Here is a simple implementation of the above algorithm. Queue is implemented
using an array with maximum size of 500. We can implement queue as linked list
also.
// Iterative Queue based Java program to do level order traversal
// of Binary Tree
  
/* importing the inbuilt java classes required for the program */
import java.util.Queue;
import java.util.LinkedList;
  
/* Class to represent Tree node */
class Node {
    int data;
    Node left, right;
  
    public Node(int item) {
        data = item;
        left = null;
        right = null;
    }
}
  
/* Class to print Level Order Traversal */
class BinaryTree {
  
    Node root;
  
    /* Given a binary tree. Print its nodes in level order
     using array for implementing queue  */
    void printLevelOrder() 
    {
        Queue<Node> queue = new LinkedList<Node>();
        queue.add(root);
        while (!queue.isEmpty()) 
        {
  
            /* poll() removes the present head.
            For more information on poll() visit 
            http://www.tutorialspoint.com/java/util/linkedlist_poll.htm */
            Node tempNode = queue.poll();
            System.out.print(tempNode.data + " ");
  
            /*Enqueue left child */
            if (tempNode.left != null) {
                queue.add(tempNode.left);
            }
  
            /*Enqueue right child */
            if (tempNode.right != null) {
                queue.add(tempNode.right);
            }
        }
    }
  
    public static void main(String args[]) 
    {
        /* creating a binary tree and entering 
         the nodes */
        BinaryTree tree_level = new BinaryTree();
        tree_level.root = new Node(1);
        tree_level.root.left = new Node(2);
        tree_level.root.right = new Node(3);
        tree_level.root.left.left = new Node(4);
        tree_level.root.left.right = new Node(5);
  
        System.out.println("Level order traversal of binary tree is - ");
        tree_level.printLevelOrder();
    }
}
Output:
Level order traversal of binary tree is -
12345
Time Complexity: O(n) where n is number of nodes in the binary tree

Find n-th node of inorder traversal


Given the binary tree and you have to find out the n-th node of inorder traversal.
Examples:
Input : n = 4
10
/ \
20 30
/ \
40 50
Output : 10
Inorder Traversal is : 40 20 50 10 30

Input : n = 3
7
/ \
2 3
/ \
8 5
Output : 8
Inorder: 2 7 8 3 5
3th node is 8

We do simple Inorder Traversal. While doing the traversal, we keep track of count of
nodes visited so far. When count becomes n, we print the node.
Below is the implementation of above approach.
// Java  program for  nth nodes of  inorder traversals 
  
import java.util. *;
  
class Solution
{
static int count =0;  
/* A binary tree node has data, pointer to left child 
and a pointer to right child */
static class Node { 
    int data; 
     Node left; 
     Node right; 

    
/* Helper function that allocates a new node with the 
given data and null left and right pointers. */
 static Node newNode(int data) 

     Node node = new Node(); 
    node.data = data; 
    node.left = null; 
    node.right = null; 
    
    return (node); 

    
  
/* Given a binary tree, print its nth nodes of inorder*/
static void NthInorder( Node node, int n) 
{  
    if (node == null) 
        return; 
    
    if (count <= n) { 
        /* first recur on left child */
        NthInorder(node.left, n); 
        count++; 
    
        // when count = n then print element 
        if (count == n) 
            System.out.printf("%d ", node.data); 
    
        /* now recur on right child */
        NthInorder(node.right, n); 
    } 

    
/* Driver program to test above functions*/
public static void main(String args[])

     Node root = newNode(10); 
    root.left = newNode(20); 
    root.right = newNode(30); 
    root.left.left = newNode(40); 
    root.left.right = newNode(50); 
    
    int n = 4; 
    
    NthInorder(root, n); 

}
  
Output:
10
Time Complexity: O(n)

Reverse Level Order Traversal


We have discussed level order traversal of a post in previous post. The idea is to
print last level first, then second last level, and so on. Like Level order traversal,
every level is printed from left to right.

Example Tree

Reverse Level order traversal of the above tree is “4 5 2 3 1”.


Both methods for normal level order traversal can be easily modified to do reverse
level order traversal.
METHOD 1 (Recursive function to print a given level)
We can easily modify the method 1 of the normal level order traversal. In method 1,
we have a method printGivenLevel() which prints a given level number. The only
thing we need to change is, instead of calling printGivenLevel() from first level to last
level, we call it from last level to first level.
// A recursive java program to print reverse level order traversal
   
// A binary tree node
class Node 
{
    int data;
    Node left, right;
       
    Node(int item) 
    {
        data = item;
        left = right;
    }
}
   
class BinaryTree 
{
    Node root;
   
    /* Function to print REVERSE level order traversal a tree*/
    void reverseLevelOrder(Node node) 
    {
        int h = height(node);
        int i;
        for (i = h; i >= 1; i--) 
        //THE ONLY LINE DIFFERENT FROM NORMAL LEVEL ORDER
        {
            printGivenLevel(node, i);
        }
    }
   
    /* Print nodes at a given level */
    void printGivenLevel(Node node, int level) 
    {
        if (node == null)
            return;
        if (level == 1)
            System.out.print(node.data + " ");
        else if (level > 1) 
        {
            printGivenLevel(node.left, level - 1);
            printGivenLevel(node.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);
        }
    }
   
    // Driver program to test above functions
    public static void main(String args[]) 
    {
        BinaryTree tree = new BinaryTree();
   
        // Let us create trees shown in above diagram
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
           
        System.out.println("Level Order traversal of binary tree is : ");
        tree.reverseLevelOrder(tree.root);
    }
}
   
Output:
Level Order traversal of binary tree is
45231
Time Complexity: The worst case time complexity of this method is O(n^2). 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).
METHOD 2 (Using Queue and Stack)
The method 2 of normal level order traversal can also be easily modified to print
level order traversal in reverse order. The idea is to use a stack to get the reverse
level order. If we do normal level order traversal and instead of printing a node, push
the node to a stack and then print contents of stack, we get “5 4 3 2 1” for above
example tree, but output should be “4 5 2 3 1”. So to get the correct sequence (left
to right at every level), we process children of a node in reverse order, we first push
the right subtree to stack, then left subtree.

// A recursive java program to print reverse level order traversal


// using stack and queue
   
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
   
/* A binary tree node has data, pointer to left and right children */
class Node 
{
    int data;
    Node left, right;
   
    Node(int item) 
    {
        data = item;
        left = right;
    }
}
   
class BinaryTree 
{
    Node root;
   
    /* Given a binary tree, print its nodes in reverse level order */
    void reverseLevelOrder(Node node) 
    {
        Stack<Node> S = new Stack();
        Queue<Node> Q = new LinkedList();
        Q.add(node);
   
        // Do something like normal level order traversal order.Following
        // are the differences with normal level order traversal
        // 1) Instead of printing a node, we push the node to stack
        // 2) Right subtree is visited before left subtree
        while (Q.isEmpty() == false) 
        {
            /* Dequeue node and make it root */
            node = Q.peek();
            Q.remove();
            S.push(node);
   
            /* Enqueue right child */
            if (node.right != null)
                // NOTE: RIGHT CHILD IS ENQUEUED BEFORE LEFT
                Q.add(node.right); 
                  
            /* Enqueue left child */
            if (node.left != null)
                Q.add(node.left);
        }
   
        // Now pop all items from stack one by one and print them
        while (S.empty() == false) 
        {
            node = S.peek();
            System.out.print(node.data + " ");
            S.pop();
        }
    }
   
    // Driver program to test above functions
    public static void main(String args[]) 
    {
        BinaryTree tree = new BinaryTree();
   
        // Let us create trees shown in above diagram
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
        tree.root.right.left = new Node(6);
        tree.root.right.right = new Node(7);
   
        System.out.println("Level Order traversal of binary tree is :");
        tree.reverseLevelOrder(tree.root);
   
    }
}
   Output:
Level Order traversal of binary tree is
4567231
Time Complexity: O(n) where n is number of nodes in the binary tree.

Iterative Preorder Traversal


Given a Binary Tree, write an iterative function to print Preorder traversal of the
given binary tree.
Refer this for recursive preorder traversal of Binary Tree. To convert an inherently
recursive procedures to iterative, we need an explicit stack. Following is a simple
stack based iterative process to print Preorder traversal.
1) Create an empty stack nodeStack and push root node to stack.
2) Do following while nodeStack is not empty.
….a) Pop an item from stack and print it.
….b) Push right child of popped item to stack
….c) Push left child of popped item to stack
Right child is pushed before left child to make sure that left subtree is processed
first.
// Java program to implement iterative preorder traversal
import java.util.Stack;
  
// A binary tree node
class Node {
  
    int data;
    Node left, right;
  
    Node(int item) {
        data = item;
        left = right = null;
    }
}
  
class BinaryTree {
  
    Node root;
      
    void iterativePreorder()
    {
        iterativePreorder(root);
    }
  
    // An iterative process to print preorder traversal of Binary tree
    void iterativePreorder(Node node) {
          
        // Base Case
        if (node == null) {
            return;
        }
  
        // Create an empty stack and push root to it
        Stack<Node> nodeStack = new Stack<Node>();
        nodeStack.push(root);
  
        /* Pop all items one by one. Do following for every popped item
         a) print it
         b) push its right child
         c) push its left child
         Note that right child is pushed first so that left is processed
first */
        while (nodeStack.empty() == false) {
              
            // Pop the top item from stack and print it
            Node mynode = nodeStack.peek();
            System.out.print(mynode.data + " ");
            nodeStack.pop();
  
            // Push right and left children of the popped node to stack
            if (mynode.right != null) {
                nodeStack.push(mynode.right);
            }
            if (mynode.left != null) {
                nodeStack.push(mynode.left);
            }
        }
    }
  
    // driver program to test above functions
    public static void main(String args[]) {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(10);
        tree.root.left = new Node(8);
        tree.root.right = new Node(2);
        tree.root.left.left = new Node(3);
        tree.root.left.right = new Node(5);
        tree.root.right.left = new Node(2);
        tree.iterativePreorder();
  
    }
}

Output:
10 8 3 5 2 2

Construction & Conversion :

Construct Tree from given Inorder and


Preorder traversals
Let us consider the below traversals:
Inorder sequence: D B E A F C
Preorder sequence: A B D E C F
In a Preorder sequence, leftmost element is the root of the tree. So we know ‘A’ is
root for given sequences. By searching ‘A’ in Inorder sequence, we can find out all
elements on left side of ‘A’ are in left subtree and elements on right are in right
subtree. So we know below structure now.
A
/ \
/ \
DBE FC
We recursively follow above steps and get the following tree.
A
/ \
/ \
B C
/\ /
/ \ /
D E F
Algorithm: buildTree()
1) Pick an element from Preorder. Increment a Preorder Index Variable (preIndex in
below code) to pick next element in next recursive call.
2) Create a new tree node tNode with the data as picked element.
3) Find the picked element’s index in Inorder. Let the index be inIndex.
4) Call buildTree for elements before inIndex and make the built tree as left subtree
of tNode.
5) Call buildTree for elements after inIndex and make the built tree as right subtree
of tNode.
6) return tNode.

// Java program to construct a tree using inorder and preorder traversal


  
/* A binary tree node has data, pointer to left child
   and a pointer to right child */
class Node {
    char data;
    Node left, right;
  
    Node(char item)
    {
        data = item;
        left = right = null;
    }
}
  
class BinaryTree {
    Node root;
    static int preIndex = 0;
  
    /* Recursive function to construct binary of size len from
       Inorder traversal in[] and Preorder traversal pre[].
       Initial values of inStrt and inEnd should be 0 and len -1.  
       The function doesn't do any error checking for cases where 
       inorder and preorder do not form a tree */
    Node buildTree(char in[], char pre[], int inStrt, int inEnd)
    {
        if (inStrt > inEnd)
            return null;
  
        /* Pick current node from Preorder traversal using preIndex
           and increment preIndex */
        Node tNode = new Node(pre[preIndex++]);
  
        /* If this node has no children then return */
        if (inStrt == inEnd)
            return tNode;
  
        /* Else find the index of this node in Inorder traversal */
        int inIndex = search(in, inStrt, inEnd, tNode.data);
  
        /* Using index in Inorder traversal, construct left and
           right subtress */
        tNode.left = buildTree(in, pre, inStrt, inIndex - 1);
        tNode.right = buildTree(in, pre, inIndex + 1, inEnd);
  
        return tNode;
    }
  
    /* UTILITY FUNCTIONS */
  
    /* Function to find index of value in arr[start...end]
     The function assumes that value is present in in[] */
    int search(char arr[], int strt, int end, char value)
    {
        int i;
        for (i = strt; i <= end; i++) {
            if (arr[i] == value)
                return i;
        }
        return i;
    }
  
    /* This funtcion is here just to test buildTree() */
    void printInorder(Node node)
    {
        if (node == null)
            return;
  
        /* first recur on left child */
        printInorder(node.left);
  
        /* then print the data of node */
        System.out.print(node.data + " ");
  
        /* now recur on right child */
        printInorder(node.right);
    }
  
    // driver program to test above functions
    public static void main(String args[])
    {
        BinaryTree tree = new BinaryTree();
        char in[] = new char[] { 'D', 'B', 'E', 'A', 'F', 'C' };
        char pre[] = new char[] { 'A', 'B', 'D', 'E', 'C', 'F' };
        int len = in.length;
        Node root = tree.buildTree(in, pre, 0, len - 1);
  
        // building the tree by printing inorder traversal
        System.out.println("Inorder traversal of constructed tree is : ");
        tree.printInorder(root);
    }
}
Output:
Inorder traversal of the constructed tree is
DBEAFC
Time Complexity: O(n^2). Worst case occurs when tree is left skewed. Example
Preorder and Inorder traversals for worst case are {A, B, C, D} and {D, C, B, A}.

Construct a tree from Inorder and Level


order traversals | Set 1
Given inorder and level-order traversals of a Binary Tree, construct the Binary Tree.
Following is an example to illustrate the problem.

Input: Two arrays that represent Inorder


and level order traversals of a
Binary Tree
in[] = {4, 8, 10, 12, 14, 20, 22};
level[] = {20, 8, 22, 4, 12, 10, 14};
Output: Construct the tree represented
by the two arrays.
For the above two arrays, the
constructed tree is shown in
the diagram on right side
The following post can be considered as a prerequisite for this.
Let us consider the above example.
in[] = {4, 8, 10, 12, 14, 20, 22};
level[] = {20, 8, 22, 4, 12, 10, 14};
In a Levelorder sequence, the first element is the root of the tree. So we know ’20’ is
root for given sequences. By searching ’20’ in Inorder sequence, we can find out all
elements on left side of ‘20’ are in left subtree and elements on right are in right
subtree. So we know below structure now.
20
/ \
/ \
{4,8,10,12,14} {22}
Let us call {4,8,10,12,14} as left subarray in Inorder traversal and {22} as right
subarray in Inorder traversal.
In level order traversal, keys of left and right subtrees are not consecutive. So we
extract all nodes from level order traversal which are in left subarray of Inorder
traversal. To construct the left subtree of root, we recur for the extracted elements
from level order traversal and left subarray of inorder traversal. In the above
example, we recur for following two arrays.
// Recur for following arrays to construct the left subtree
In[] = {4, 8, 10, 12, 14}
level[] = {8, 4, 12, 10, 14}
Similarly, we recur for following two arrays and construct the right subtree.
// Recur for following arrays to construct the right subtree
In[] = {22}
level[] = {22}
Following is the implementation of the above approach.
// Java program to construct a tree from level order and
// and inorder traversal
   
// A binary tree node
class Node 
{
    int data;
    Node left, right;
   
    Node(int item) 
    {
        data = item;
        left = right = null;
    }
   
    public void setLeft(Node left) 
    {
        this.left = left;
    }
   
    public void setRight(Node right) 
    {
        this.right = right;
    }
}
   
class Tree 
{
    Node root;
   
    Node buildTree(int in[], int level[]) 
    {
        Node startnode = null;
        return constructTree(startnode, level, in, 0, in.length - 1);
    }
   
    Node constructTree(Node startNode, int[] levelOrder, int[] inOrder,
            int inStart, int inEnd) 
    {
   
        // if start index is more than end index
        if (inStart > inEnd)
            return null;
   
        if (inStart == inEnd)
            return new Node(inOrder[inStart]);
              
        boolean found = false;
        int index = 0;
   
        // it represents the index in inOrder array of element that
        // appear first in levelOrder array.
        for (int i = 0; i < levelOrder.length - 1; i++) 
        {
            int data = levelOrder[i];
            for (int j = inStart; j < inEnd; j++) 
            {
                if (data == inOrder[j]) 
                {
                    startNode = new Node(data);
                    index = j;
                    found = true;
                    break;
                }
            }
            if (found == true)
                break;
        }
   
        //elements present before index are part of left child of
startNode.
        //elements present after index are part of right child of
startNode.
        startNode.setLeft(constructTree(startNode, levelOrder, inOrder, 
                                                    inStart, index - 1));
        startNode.setRight(constructTree(startNode, levelOrder, inOrder, 
                                                     index + 1, inEnd));
   
        return startNode;
    }
   
    /* Utility function to print inorder traversal of binary tree */
    void printInorder(Node node) 
    {
        if (node == null)
            return;
        printInorder(node.left);
        System.out.print(node.data + " ");
        printInorder(node.right);
    }
   
    // Driver program to test the above functions
    public static void main(String args[]) 
    {
        Tree tree = new Tree();
        int in[] = new int[]{4, 8, 10, 12, 14, 20, 22};
        int level[] = new int[]{20, 8, 22, 4, 12, 10, 14};
        int n = in.length;
        Node node = tree.buildTree(in, level);
   
        /* Let us test the built tree by printing Inorder traversal */
        System.out.print("Inorder traversal of the constructed tree is ");
        tree.printInorder(node);
    }
}

Output:
Inorder traversal of the constructed tree is
4 8 10 12 14 20 22
An upper bound on time complexity of above method is O(n3). In the main recursive
function, extractNodes() is called which takes O(n 2) time.
Construct Complete Binary Tree from its
Linked List Representation
Given Linked List Representation of Complete Binary Tree, construct the Binary tree.
A complete binary tree can be represented in an array in the following approach.
If root node is stored at index i, its left, and right children are stored at indices 2*i+1,
2*i+2 respectively.
Suppose tree is represented by a linked list in same way, how do we convert this into
normal linked representation of binary tree where every node has data, left and right
pointers? In the linked list representation, we cannot directly access the children of
the current node unless we traverse the list.

We are mainly given level order traversal in sequential access form. We know head
of linked list is always is root of the tree. We take the first node as root and we also
know that the next two nodes are left and right children of root. So we know partial
Binary Tree. The idea is to do Level order traversal of the partially built Binary Tree
using queue and traverse the linked list at the same time. At every step, we take the
parent node from queue, make next two nodes of linked list as children of the parent
node, and enqueue the next two nodes to queue.
1. Create an empty queue.
2. Make the first node of the list as root, and enqueue it to the queue.
3. Until we reach the end of the list, do the following.
………a. Dequeue one node from the queue. This is the current parent.
………b. Traverse two nodes in the list, add them as children of the current parent.
………c. Enqueue the two nodes into the queue.

// Java program to create complete Binary Tree from its Linked List
// representation
   
// importing necessary classes
import java.util.*;
   
// A linked list node
class ListNode 
{
    int data;
    ListNode next;
    ListNode(int d)
    {
        data = d;
        next = null;
    }
}
   
// A binary tree node
class BinaryTreeNode 
{
    int data;
    BinaryTreeNode left, right = null;
    BinaryTreeNode(int data)
    {
        this.data = data;
        left = right = null;
    }
}
   
class BinaryTree 
{
    ListNode head;
    BinaryTreeNode root;
   
    // Function to insert a node at the beginning of
    // the Linked List
    void push(int new_data) 
    {
        // allocate node and assign data
        ListNode new_node = new ListNode(new_data);
   
        // link the old list off the new node
        new_node.next = head;
   
        // move the head to point to the new node
        head = new_node;
    }
   
    // converts a given linked list representing a 
    // complete binary tree into the linked 
    // representation of binary tree.
    BinaryTreeNode convertList2Binary(BinaryTreeNode node) 
    {
        // queue to store the parent nodes
        Queue<BinaryTreeNode> q = 
                       new LinkedList<BinaryTreeNode>();
   
        // Base Case
        if (head == null) 
        {
            node = null; 
            return null;
        }
   
        // 1.) The first node is always the root node, and
        //     add it to the queue
        node = new BinaryTreeNode(head.data);
        q.add(node);
   
        // advance the pointer to the next node
        head = head.next;
   
        // until the end of linked list is reached, do the
        // following steps
        while (head != null) 
        {
            // 2.a) take the parent node from the q and 
            //      remove it from q
            BinaryTreeNode parent = q.peek();
            BinaryTreeNode pp = q.poll();
               
            // 2.c) take next two nodes from the linked list.
            // We will add them as children of the current 
            // parent node in step 2.b. Push them into the
            // queue so that they will be parents to the 
            // future nodes
            BinaryTreeNode leftChild = null, rightChild = null;
            leftChild = new BinaryTreeNode(head.data);
            q.add(leftChild);
            head = head.next;
            if (head != null) 
            {
                rightChild = new BinaryTreeNode(head.data);
                q.add(rightChild);
                head = head.next;
            }
   
            // 2.b) assign the left and right children of
            //      parent
            parent.left = leftChild;
            parent.right = rightChild;
        }
           
        return node;
    }
   
    // Utility function to traverse the binary tree 
    // after conversion
    void inorderTraversal(BinaryTreeNode node) 
    {
        if (node != null) 
        {
            inorderTraversal(node.left);
            System.out.print(node.data + " ");
            inorderTraversal(node.right);
        }
    }
   
    // Driver program to test above functions
    public static void main(String[] args) 
    {
        BinaryTree tree = new BinaryTree();
        tree.push(36); /* Last node of Linked List */
        tree.push(30);
        tree.push(25);
        tree.push(15);
        tree.push(12);
        tree.push(10); /* First node of Linked List */
        BinaryTreeNode node = tree.convertList2Binary(tree.root);
   
        System.out.println("Inorder Traversal of the"+
                        " constructed Binary Tree is:");
        tree.inorderTraversal(node);
    }
}

Output:
Inorder Traversal of the constructed Binary Tree is:
25 12 30 10 36 15
Time Complexity: Time complexity of the above solution is O(n) where n is the
number of nodes.

Construct a complete binary tree from


given array in level order fashion
Given an array of elements, our task is to construct a complete binary tree from this
array in level order fashion. That is, elements from left in the array will be filled in
the tree level wise starting from level 0.
Examples:
Input : arr[] = {1, 2, 3, 4, 5, 6}
Output : Root of the following tree
1
/\
2 3
/\/
4 56

Input: arr[] = {1, 2, 3, 4, 5, 6, 6, 6, 6, 6}


Output: Root of the following tree
1
/\
2 3
/\/\
4 56 6
/\/
6 66
If we observe carefully we can see that if parent node is at index i in the array
then the left child of that node is at index (2*i + 1) and right child is at index (2*i + 2)
in the array.
Using this concept, we can easily insert the left and right nodes by choosing its
parent node. We will insert the first element present in the array as the root node at
level 0 in the tree and start traversing the array and for every node i we will insert its
both childs left and right in the tree.
Below is the recursive program to do this:

// Java program to construct binary tree from


// given array in level order fashion
  
public class Tree {
    Node root;
  
    // Tree Node
    static class Node {
        int data;
        Node left, right;
        Node(int data)
        {
            this.data = data;
            this.left = null;
            this.right = null;
        }
    }
  
    // Function to insert nodes in level order
    public Node insertLevelOrder(int[] arr, Node root,
                                                int i)
    {
        // Base case for recursion
        if (i < arr.length) {
            Node temp = new Node(arr[i]);
            root = temp;
  
            // insert left child
            root.left = insertLevelOrder(arr, root.left,
                                             2 * i + 1);
  
            // insert right child
            root.right = insertLevelOrder(arr, root.right,
                                               2 * i + 2);
        }
        return root;
    }
  
    // Function to print tree nodes in InOrder fashion
    public void inOrder(Node root)
    {
        if (root != null) {
            inOrder(root.left);
            System.out.print(root.data + " ");
            inOrder(root.right);
        }
    }
  
    // Driver program to test above function
    public static void main(String args[])
    {
        Tree t2 = new Tree();
        int arr[] = { 1, 2, 3, 4, 5, 6, 6, 6, 6 };
        t2.root = t2.insertLevelOrder(arr, t2.root, 0);
        t2.inOrder(t2.root);
    }
}

Output:
646251636
Time Complexity: O(n), where n is the total number of nodes in the tree.

Summation :

Sum of all nodes in a binary tree


Give an algorithm for finding the sum of all elements in a binary tree.

In the above binary tree sum = 106.


The idea is to recursively, call left subtree sum, right subtree sum and add their
values to current node’s data.
// Java Program to print sum of
// all the elements of a binary tree
class GFG
{
static class Node 

    int key; 
    Node left, right; 
}
  
/* utility that allocates a new 
   Node with the given key */
static Node newNode(int key) 

    Node node = new Node(); 
    node.key = key; 
    node.left = node.right = null; 
    return (node); 

  
/* Function to find sum 
   of all the elements*/
static int addBT(Node root) 

    if (root == null) 
        return 0; 
    return (root.key + addBT(root.left) + 
                       addBT(root.right)); 

  
// Driver Code
public static void main(String args[])

    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); 
    root.right.left.right = newNode(8); 
  
    int sum = addBT(root); 
    System.out.println("Sum of all the elements is: " + sum); 

}
  

Output:
Sum of all the elements is: 36

Find sum of all left leaves in a given


Binary Tree
Given a Binary Tree, find sum of all left leaves in it. For example, sum of all left leaves
in below Binary Tree is 5+1=6.

The idea is to traverse the tree, starting from root. For every node, check if its left
subtree is a leaf. If it is, then add it to the result.

Following is the implementation of above idea.


// Java program to find sum of all left leaves
class Node 
{
    int data;
    Node left, right;
   
    Node(int item) 
    {
        data = item;
        left = right = null;
    }
}
   
class BinaryTree 
{
    Node root;
   
    // A utility function to check if a given node is leaf or not
    boolean isLeaf(Node node) 
    {
        if (node == null)
            return false;
        if (node.left == null && node.right == null)
            return true;
        return false;
    }
   
     // This function returns sum of all left leaves in a given
     // binary tree
    int leftLeavesSum(Node node) 
    {
        // Initialize result
        int res = 0;
   
        // Update result if root is not NULL
        if (node != null) 
        {
            // If left of root is NULL, then add key of
            // left child
            if (isLeaf(node.left))
                res += node.left.data;
            else // Else recur for left child of root
                res += leftLeavesSum(node.left);
   
            // Recur for right child of root and update res
            res += leftLeavesSum(node.right);
        }
   
        // return result
        return res;
    }
   
    // Driver program
    public static void main(String args[]) 
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(20);
        tree.root.left = new Node(9);
        tree.root.right = new Node(49);
        tree.root.left.right = new Node(12);
        tree.root.left.left = new Node(5);
        tree.root.right.left = new Node(23);
        tree.root.right.right = new Node(52);
        tree.root.left.right.right = new Node(12);
        tree.root.right.right.left = new Node(50);
   
        System.out.println("The sum of leaves is " + 
                                       tree.leftLeavesSum(tree.root));
    }
}
Output:
Sum of left leaves is 78
Time complexity of the above solution is O(n) where n is number of nodes in Binary
Tree.
// Java program to find sum of all left leaves
class Node 
{
    int data;
    Node left, right;
   
    Node(int item) {
        data = item;
        left = right = null;
    }
}
   
// Passing sum as accumulator and implementing pass by reference 
// of sum variable 
class Sum 
{
    int sum = 0;
}
   
class BinaryTree 
{
    Node root;
   
    /* Pass in a sum variable as an accumulator */
    void leftLeavesSumRec(Node node, boolean isleft, Sum summ) 
    {
        if (node == null)
            return;
   
        // Check whether this node is a leaf node and is left.
        if (node.left == null && node.right == null && isleft)
            summ.sum = summ.sum + node.data;
   
        // Pass true for left and false for right
        leftLeavesSumRec(node.left, true, summ);
        leftLeavesSumRec(node.right, false, summ);
    }
   
    // A wrapper over above recursive function
    int leftLeavesSum(Node node) 
    {
        Sum suum = new Sum();
          
        // use the above recursive function to evaluate sum
        leftLeavesSumRec(node, false, suum);
   
        return suum.sum;
    }
   
    // Driver program
    public static void main(String args[]) 
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(20);
        tree.root.left = new Node(9);
        tree.root.right = new Node(49);
        tree.root.left.right = new Node(12);
        tree.root.left.left = new Node(5);
        tree.root.right.left = new Node(23);
        tree.root.right.right = new Node(52);
        tree.root.left.right.right = new Node(12);
        tree.root.right.right.left = new Node(50);
   
        System.out.println("The sum of leaves is " + 
                                    tree.leftLeavesSum(tree.root));
    }
}

Output:
Sum of left leaves is 78

Find sum of all right leaves in a given


Binary Tree
Given a Binary Tree, find sum of all right leaves in it.
Example :
Input :
1
/ \
2 3
/ \ \
4 5 8
\ / \
2 6 7

Output :
sum = 2 + 5 + 7 = 14

The idea is to traverse the tree starting from the root and check if the node is the
leaf node or not. If the node is the right leaf than add data of right leaf to sum
variable.
Following is the implementation for the same.
// Java program to find total 
// sum of right leaf nodes 
class GFG
{
  
    // sum
    static int sum = 0;
      
// node of binary tree 
static class Node

    int data; 
    Node left, right; 
}; 
  
// return new node 
static Node addNode(int data)

    Node temp = new Node(); 
    temp.data = data; 
    temp.left = temp.right = null; 
    return temp;

  
// utility function to calculate 
// sum of right leaf nodes 
static void rightLeafSum(Node root)

    if(root == null) 
        return; 
  
    // check if the right child
    // of root is leaf node 
    if(root.right != null) 
        if(root.right.left == null && 
           root.right.right == null) 
            sum += root.right.data; 
  
    rightLeafSum(root.left); 
    rightLeafSum(root.right); 

  
// Driver Code
public static void main(String args[])

      
    //contruct binary tree 
    Node root = addNode(1); 
    root.left = addNode(2); 
    root.left.left = addNode(4); 
    root.left.right = addNode(5); 
    root.left.left.right = addNode(2); 
    root.right = addNode(3); 
    root.right.right = addNode(8); 
    root.right.right.left = addNode(6); 
    root.right.right.right = addNode(7); 
      
    // variable to store sum 
    // of right leaves 
    sum = 0; 
    rightLeafSum(root); 
    System.out.println( sum ); 
    } 
}

Output:
14

You might also like