Skip to content
Related Articles

Related Articles

Improve Article
Diagonal Traversal of Binary Tree
  • Difficulty Level : Medium
  • Last Updated : 02 Jun, 2021

Consider lines of slope -1 passing between nodes. Given a Binary Tree, print all diagonal elements in a binary tree belonging to the same line.

Input : Root of below tree

unnamed

Output : 
Diagonal Traversal of binary tree : 
 8 10 14
 3 6 7 13
 1 4

The idea is to use a map. We use different slope distances and use them as key in the map. Value in the map is a vector (or dynamic array) of nodes. We traverse the tree to store values in the map. Once map is built, we print the contents of it. 
Below is the implementation of the above idea.

C++




// C++ program for diagnoal
// traversal of Binary Tree
#include <bits/stdc++.h>
using namespace std;
 
// Tree node
struct Node
{
    int data;
    Node *left, *right;
};
 
/* root - root of the binary tree
   d -  distance of current line from rightmost
        -topmost slope.
   diagonalPrint - multimap to store Diagonal
                   elements (Passed by Reference) */
void diagonalPrintUtil(Node* root, int d,
                map<int, vector<int>> &diagonalPrint)
{
    // Base case
    if (!root)
        return;
 
    // Store all nodes of same
    // line together as a vector
    diagonalPrint[d].push_back(root->data);
 
    // Increase the vertical
    // distance if left child
    diagonalPrintUtil(root->left,
                      d + 1, diagonalPrint);
 
    // Vertical distance remains
    // same for right child
    diagonalPrintUtil(root->right,
                         d, diagonalPrint);
}
 
// Print diagonal traversal
// of given binary tree
void diagonalPrint(Node* root)
{
     
    // create a map of vectors
    // to store Diagonal elements
    map<int, vector<int> > diagonalPrint;
    diagonalPrintUtil(root, 0, diagonalPrint);
 
    cout << "Diagonal Traversal of binary tree : \n";
    for (auto it :diagonalPrint)
    {
        vector<int> v=it.second;
        for(auto it:v)
          cout<<it<<" ";
        cout<<endl;
    }
}
 
// Utility method to create a new node
Node* newNode(int data)
{
    Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return node;
}
 
// Driver program
int main()
{
    Node* root = newNode(8);
    root->left = newNode(3);
    root->right = newNode(10);
    root->left->left = newNode(1);
    root->left->right = newNode(6);
    root->right->right = newNode(14);
    root->right->right->left = newNode(13);
    root->left->right->left = newNode(4);
    root->left->right->right = newNode(7);
 
    /*  Node* root = newNode(1);
        root->left = newNode(2);
        root->right = newNode(3);
        root->left->left = newNode(9);
        root->left->right = newNode(6);
        root->right->left = newNode(4);
        root->right->right = newNode(5);
        root->right->left->right = newNode(7);
        root->right->left->left = newNode(12);
        root->left->right->left = newNode(11);
        root->left->left->right = newNode(10);*/
 
    diagonalPrint(root);
 
    return 0;
}

Java




// Java program for diagonal
// traversal of Binary Tree
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Vector;
 
public class DiagonalTraversalBTree
{
    // Tree node
    static class Node
    {
        int data;
        Node left;
        Node right;
         
        //constructor
        Node(int data)
        {
            this.data=data;
            left = null;
            right =null;
        }
    }
     
    /* root - root of the binary tree
       d -  distance of current line from rightmost
            -topmost slope.
       diagonalPrint - HashMap to store Diagonal
                       elements (Passed by Reference) */
    static void diagonalPrintUtil(Node root,int d,
          HashMap<Integer,Vector<Integer>> diagonalPrint)
    {
         
         // Base case
        if (root == null)
            return;
         
        // get the list at the particular d value
        Vector<Integer> k = diagonalPrint.get(d);
         
        // k is null then create a
        // vector and store the data
        if (k == null)
        {
            k = new Vector<>();
            k.add(root.data);
        }
         
        // k is not null then update the list
        else
        {
            k.add(root.data);
        }
         
        // Store all nodes of same line
        // together as a vector
        diagonalPrint.put(d,k);
         
        // Increase the vertical distance
        // if left child
        diagonalPrintUtil(root.left,
                         d + 1, diagonalPrint);
          
        // Vertical distance remains
        // same for right child
        diagonalPrintUtil(root.right,
                          d, diagonalPrint);
    }
     
    // Print diagonal traversal
    // of given binary tree
    static void diagonalPrint(Node root)
    {
         
        // create a map of vectors
        // to store Diagonal elements
        HashMap<Integer,Vector<Integer>>
             diagonalPrint = new HashMap<>();
        diagonalPrintUtil(root, 0, diagonalPrint);
         
        System.out.println("Diagonal Traversal
                                of Binnary Tree");
        for (Entry<Integer, Vector<Integer>> entry :
                          diagonalPrint.entrySet())
        {
            System.out.println(entry.getValue());
        }
    }
     
    // Driver program
    public static void main(String[] args)
    {
         
        Node root = new Node(8);
        root.left = new Node(3);
        root.right = new Node(10);
        root.left.left = new Node(1);
        root.left.right = new Node(6);
        root.right.right = new Node(14);
        root.right.right.left = new Node(13);
        root.left.right.left = new Node(4);
        root.left.right.right = new Node(7);
         
        diagonalPrint(root);
    }
}
// This code is contributed by Sumit Ghosh

Python




# Python program for diagonal
# traversal of Binary Tree
 
# A binary tree node
class Node:
 
    # Constructor to create a
    # new binary tree node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
 
""" root - root of the binary tree
   d -  distance of current line from rightmost
        -topmost slope.
   diagonalPrint - multimap to store Diagonal
                   elements (Passed by Reference) """
def diagonalPrintUtil(root, d, diagonalPrintMap):
     
    # Base Case
    if root is None:
        return
 
    # Store all nodes of same line
    # together as a vector
    try :
        diagonalPrintMap[d].append(root.data)
    except KeyError:
        diagonalPrintMap[d] = [root.data]
 
    # Increase the vertical distance
    # if left child
    diagonalPrintUtil(root.left,
                        d+1, diagonalPrintMap)
     
    # Vertical distance remains
    # same for right child
    diagonalPrintUtil(root.right,
                           d, diagonalPrintMap)
 
 
 
# Print diagonal traversal of given binary tree
def diagonalPrint(root):
 
    # Create a dict to store diagnoal elements
    diagonalPrintMap = dict()
     
    # Find the diagonal traversal
    diagonalPrintUtil(root, 0, diagonalPrintMap)
 
    print "Diagonal Traversal of binary tree : "
    for i in diagonalPrintMap:
        for j in diagonalPrintMap[i]:
            print j,
        print ""
 
 
# Driver Program
root = Node(8)
root.left = Node(3)
root.right = Node(10)
root.left.left = Node(1)
root.left.right = Node(6)
root.right.right = Node(14)
root.right.right.left = Node(13)
root.left.right.left = Node(4)
root.left.right.right = Node(7)
 
diagonalPrint(root)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)
Output
Diagonal Traversal of binary tree : 
8 10 14 
3 6 7 13 
1 4 

The time complexity of this solution is O( N logN ) and the space complexity is O( N )



We can solve the same problem using queue and iterative algorithm. 

Python3




from collections import deque
 
# A binary tree node
class Node:
 
    # Constructor to create a
    # new binary tree node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
         
def diagonal(root):
    out = []
    node = root
     
    ## queue to store left nodes
    left_q = deque()
    while node:
           
        ### append data to output array
        out.append(node.data)
         
        ## if left available add it to the queue
        if node.left:
            left_q.appendleft(node.left)
         
        ## if right is available change the node
        if node.right:
            node = node.right
        else:
               
            ## else pop the left_q
            if len(left_q)>=1:
                node = left_q.pop()
            else:
                node = None
    return out
   
# Driver Code
root = Node(8)
root.left = Node(3)
root.right = Node(10)
root.left.left = Node(1)
root.left.right = Node(6)
root.right.right = Node(14)
root.right.right.left = Node(13)
root.left.right.left = Node(4)
root.left.right.right = Node(7)
 
print(diagonal(root))
Output
[8, 10, 14, 3, 6, 7, 13, 1, 4]

The time complexity of this solution is O( N logN ) and the space complexity is O( N )

Approach 2 : Using Queue.

Every node will help to generate the next diagonal. We will push the element in the queue only when its left is available. We will process the node and move to its right.

Code:

C++




#include <bits/stdc++.h>
using namespace std;
 
struct Node
{
    int data;
    Node *left, *right;
};
 
Node* newNode(int data)
{
    Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return node;
}
 
vector <vector <int>> result;
void diagonalPrint(Node* root)
{
    if(root == NULL)
        return;
 
    queue <Node*> q;
    q.push(root);
 
    while(!q.empty())
    {
        int size = q.size();
        vector <int> answer;
 
        while(size--)
        {
            Node* temp = q.front();
            q.pop();
 
            // traversing each component;
            while(temp)
            {
                answer.push_back(temp->data);
 
                if(temp->left)
                    q.push(temp->left);
 
                temp = temp->right;
            }
        }
        result.push_back(answer);
    }
}
 
int main()
{
    Node* root = newNode(8);
    root->left = newNode(3);
    root->right = newNode(10);
    root->left->left = newNode(1);
    root->left->right = newNode(6);
    root->right->right = newNode(14);
    root->right->right->left = newNode(13);
    root->left->right->left = newNode(4);
    root->left->right->right = newNode(7);
     
    diagonalPrint(root);
 
    for(int i=0 ; i<result.size() ; i++)
    {
        for(int j=0 ; j<result[i].size() ; j++)
            cout<<result[i][j]<<"  ";
        cout<<endl;
    }
 
    return 0;
}
Output:
8  10  14
3  6  7  13
1  4

Time Complexity : O(N), because at a node will be traversed 2 times. hence O(2N) == O(N).

Space Complexity : O(N), because we are using queue data structure.

This article is contributed by Aditya Goel. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes 




My Personal Notes arrow_drop_up
Recommended Articles
Page :