Iterative diagonal traversal of binary tree
Last Updated :
26 Sep, 2024
Given a Binary Tree, the task is to print the diagonal traversal of the binary tree.
Note: If the diagonal element are present in two different subtrees, then left subtree diagonal element should be taken first and then right subtree.
Example:
Input:
Output: 8 10 14 3 6 7 13 1 4
Explanation: The above is the diagonal elements in a binary tree that belong to the same line.
[Expected Approach - 1] Using Queue with delimiter - O(n) Time and O(n) Space
The idea is to traverse the binary tree in level order manner using a queue. Push the root node and null pointer into the queue. For each node (starting from root), append its value to the resultant list. Push its left child node into queue if it exists, and set it to its right child node. If the current node is null, it means the starting of the next diagonal. So set the current node to the front node of the queue and pop from queue.
Below is the implementation of the above approach:
C++
// C++ program to print diagonal view
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node (int x) {
data = x;
left = nullptr;
right = nullptr;
}
};
// Iterative function to print diagonal view
vector<int> diagonal(Node* root) {
vector<int> ans;
// base case
if (root == nullptr)
return ans;
queue<Node*> q;
q.push(root);
q.push(nullptr);
while (!q.empty()) {
Node* curr = q.front();
q.pop();
// if current is delimiter then insert another
// null for next diagonal
if (curr == nullptr) {
// if tree has been traversed
if (q.empty()) break;
q.push(nullptr);
}
// Else print the current diagonal
else {
while (curr != nullptr) {
ans.push_back(curr->data);
// if left child is present
// push into queue
if (curr->left != nullptr)
q.push(curr->left);
// current equals to right child
curr = curr->right;
}
}
}
return ans;
}
void printList(vector<int> v) {
int n = v.size();
for (int i=0; i<n; i++) {
cout << v[i] << " ";
}
cout << endl;
}
int main() {
// Create a hard coded tree
// 8
// / \
// 3 10
// / / \
// 1 6 14
// / \ /
// 4 7 13
Node* root = new Node(8);
root->left = new Node(3);
root->right = new Node(10);
root->left->left = new Node(1);
root->right->left = new Node(6);
root->right->right = new Node(14);
root->right->right->left = new Node(13);
root->right->left->left = new Node(4);
root->right->left->right = new Node(7);
vector<int> ans = diagonal(root);
printList(ans);
}
Java
// Java Program to print diagonal view
import java.util.*;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Iterative function to print diagonal view
static ArrayList<Integer> diagonalPrint(Node root) {
ArrayList<Integer> ans = new ArrayList<>();
// base case
if (root == null)
return ans;
Queue<Node> q = new LinkedList<>();
q.add(root);
q.add(null);
while (!q.isEmpty()) {
Node curr = q.poll();
// if current is delimiter then insert another
// null for next diagonal
if (curr == null) {
// if tree has been traversed
if (q.isEmpty()) break;
q.add(null);
}
// Else print the current diagonal
else {
while (curr != null) {
ans.add(curr.data);
// if left child is present
// push into queue
if (curr.left != null)
q.add(curr.left);
// current equals to right child
curr = curr.right;
}
}
}
return ans;
}
static void printList(ArrayList<Integer> v) {
for (int i = 0; i < v.size(); i++) {
System.out.print(v.get(i) + " ");
}
System.out.println();
}
public static void main(String[] args) {
// Create a hard coded tree
// 8
// / \
// 3 10
// / / \
// 1 6 14
// / \ /
// 4 7 13
Node root = new Node(8);
root.left = new Node(3);
root.right = new Node(10);
root.left.left = new Node(1);
root.right.left = new Node(6);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
root.right.left.left = new Node(4);
root.right.left.right = new Node(7);
ArrayList<Integer> ans = diagonalPrint(root);
printList(ans);
}
}
Python
# Python Program to print diagonal view
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Iterative function to print diagonal view
def diagonal_print(root):
ans = []
if root is None:
return ans
q = []
q.append(root)
q.append(None)
while len(q) > 0:
curr = q.pop(0)
# if current is delimiter then insert another
# null for next diagonal
if curr is None:
# if tree has been traversed
if len(q) == 0:
break
q.append(None)
# Else print the current diagonal
else:
while curr is not None:
ans.append(curr.data)
# if left child is present
# push into queue
if curr.left is not None:
q.append(curr.left)
# current equals to right child
curr = curr.right
return ans
def print_list(v):
for i in range(len(v)):
print(v[i], end=" ")
print()
if __name__ == "__main__":
# Create a hard coded tree
# 8
# / \
# 3 10
# / / \
# 1 6 14
# / \ /
# 4 7 13
root = Node(8)
root.left = Node(3)
root.right = Node(10)
root.left.left = Node(1)
root.right.left = Node(6)
root.right.right = Node(14)
root.right.right.left = Node(13)
root.right.left.left = Node(4)
root.right.left.right = Node(7)
ans = diagonal_print(root)
print_list(ans)
C#
// C# Program to print diagonal view
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Iterative function to print diagonal view
static List<int> DiagonalPrint(Node root) {
List<int> ans = new List<int>();
// base case
if (root == null)
return ans;
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
q.Enqueue(null);
while (q.Count > 0) {
Node curr = q.Dequeue();
// if current is delimiter then insert another
// null for next diagonal
if (curr == null) {
// if tree has been traversed
if (q.Count == 0) break;
q.Enqueue(null);
}
// Else print the current diagonal
else {
while (curr != null) {
ans.Add(curr.data);
// if left child is present
// push into queue
if (curr.left != null)
q.Enqueue(curr.left);
// current equals to right child
curr = curr.right;
}
}
}
return ans;
}
static void PrintList(List<int> v) {
for (int i = 0; i < v.Count; i++) {
Console.Write(v[i] + " ");
}
Console.WriteLine();
}
static void Main() {
// Create a hard coded tree
// 8
// / \
// 3 10
// / / \
// 1 6 14
// / \ /
// 4 7 13
Node root = new Node(8);
root.left = new Node(3);
root.right = new Node(10);
root.left.left = new Node(1);
root.right.left = new Node(6);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
root.right.left.left = new Node(4);
root.right.left.right = new Node(7);
List<int> ans = DiagonalPrint(root);
PrintList(ans);
}
}
JavaScript
// JavaScript Program to print diagonal view
class Node {
constructor(x) {
this.key = x;
this.left = null;
this.right = null;
}
}
// Iterative function to print diagonal view
function diagonalPrint(root) {
let ans = [];
// base case
if (root === null)
return ans;
let q = [];
// push root
q.push(root);
// push delimiter
q.push(null);
while (q.length > 0) {
let curr = q.shift();
// if current is delimiter then insert another
// null for next diagonal
if (curr === null) {
// if tree has been traversed
if (q.length === 0) break;
q.push(null);
}
// Else print the current diagonal
else {
while (curr !== null) {
ans.push(curr.key);
// if left child is present
// push into queue
if (curr.left !== null)
q.push(curr.left);
// current equals to right child
curr = curr.right;
}
}
}
return ans;
}
function printList(v) {
for (let i = 0; i < v.length; i++) {
process.stdout.write(v[i] + " ");
}
console.log();
}
// Create a hard coded tree
// 8
// / \
// 3 10
// / / \
// 1 6 14
// / \ /
// 4 7 13
let root = new Node(8);
root.left = new Node(3);
root.right = new Node(10);
root.left.left = new Node(1);
root.right.left = new Node(6);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
root.right.left.left = new Node(4);
root.right.left.right = new Node(7);
let ans = diagonalPrint(root);
printList(ans);
Output8 10 14 3 6 7 13 1 4
Time Complexity: O(n), where n is the total number of nodes in the binary tree.
Auxiliary Space: O(n)
[Expected Approach - 2] Using Queue without delimiter - O(n) Time and O(n) Space
The idea is similar to level order traversal, use a queue, but here delimiter is not used. Little modification is to be done.
- if(curr.left != null), then add it to the queue and move curr pointer to right of curr.
- if curr = null, then remove a node from queue.
Below is the implementation of the above approach:
C++
// C++ program to print diagonal view
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node (int x) {
data = x;
left = nullptr;
right = nullptr;
}
};
// Iterative function to print diagonal view
vector<int> diagonalPrint(Node* root) {
vector<int> ans;
// base case
if (root == nullptr)
return ans;
queue<Node*> q;
// push root
q.push(root);
while (!q.empty()) {
Node* curr = q.front();
q.pop();
while (curr != nullptr) {
ans.push_back(curr->data);
// if left child is present
// push into queue
if (curr->left != nullptr)
q.push(curr->left);
// current equals to right child
curr = curr->right;
}
}
return ans;
}
void printList(vector<int> v) {
int n = v.size();
for (int i=0; i<n; i++) {
cout << v[i] << " ";
}
cout << endl;
}
int main() {
// Create a hard coded tree
// 8
// / \
// 3 10
// / / \
// 1 6 14
// / \ /
// 4 7 13
Node* root = new Node(8);
root->left = new Node(3);
root->right = new Node(10);
root->left->left = new Node(1);
root->right->left = new Node(6);
root->right->right = new Node(14);
root->right->right->left = new Node(13);
root->right->left->left = new Node(4);
root->right->left->right = new Node(7);
vector<int> ans = diagonalPrint(root);
printList(ans);
}
Java
// Java Program to print diagonal view
import java.util.*;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Iterative function to print diagonal view
static ArrayList<Integer> diagonalPrint(Node root) {
ArrayList<Integer> ans = new ArrayList<>();
// base case
if (root == null)
return ans;
Queue<Node> q = new LinkedList<>();
// push root
q.add(root);
while (!q.isEmpty()) {
Node curr = q.poll();
while (curr != null) {
ans.add(curr.data);
// if left child is present
// push into queue
if (curr.left != null)
q.add(curr.left);
// current equals to right child
curr = curr.right;
}
}
return ans;
}
static void printList(ArrayList<Integer> v) {
for (int i = 0; i < v.size(); i++) {
System.out.print(v.get(i) + " ");
}
System.out.println();
}
public static void main(String[] args) {
// Create a hard coded tree
// 8
// / \
// 3 10
// / / \
// 1 6 14
// / \ /
// 4 7 13
Node root = new Node(8);
root.left = new Node(3);
root.right = new Node(10);
root.left.left = new Node(1);
root.right.left = new Node(6);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
root.right.left.left = new Node(4);
root.right.left.right = new Node(7);
ArrayList<Integer> ans = diagonalPrint(root);
printList(ans);
}
}
Python
# Python Program to print diagonal view
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Iterative function to print diagonal view
def diagonal_print(root):
ans = []
# base case
if root is None:
return ans
q = []
# push root
q.append(root)
while len(q) > 0:
curr = q.pop(0)
while curr is not None:
ans.append(curr.data)
# if left child is present
# push into queue
if curr.left is not None:
q.append(curr.left)
# current equals to right child
curr = curr.right
return ans
def print_list(v):
for i in range(len(v)):
print(v[i], end=" ")
print()
if __name__ == "__main__":
# Create a hard coded tree
# 8
# / \
# 3 10
# / / \
# 1 6 14
# / \ /
# 4 7 13
root = Node(8)
root.left = Node(3)
root.right = Node(10)
root.left.left = Node(1)
root.right.left = Node(6)
root.right.right = Node(14)
root.right.right.left = Node(13)
root.right.left.left = Node(4)
root.right.left.right = Node(7)
ans = diagonal_print(root)
print_list(ans)
C#
// C# Program to print diagonal view
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Iterative function to print diagonal view
static List<int> DiagonalPrint(Node root) {
List<int> ans = new List<int>();
// base case
if (root == null)
return ans;
Queue<Node> q = new Queue<Node>();
// push root
q.Enqueue(root);
while (q.Count > 0) {
Node curr = q.Dequeue();
while (curr != null) {
ans.Add(curr.data);
// if left child is present
// push into queue
if (curr.left != null)
q.Enqueue(curr.left);
// current equals to right child
curr = curr.right;
}
}
return ans;
}
static void PrintList(List<int> v) {
for (int i = 0; i < v.Count; i++) {
Console.Write(v[i] + " ");
}
Console.WriteLine();
}
static void Main() {
// Create a hard coded tree
// 8
// / \
// 3 10
// / / \
// 1 6 14
// / \ /
// 4 7 13
Node root = new Node(8);
root.left = new Node(3);
root.right = new Node(10);
root.left.left = new Node(1);
root.right.left = new Node(6);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
root.right.left.left = new Node(4);
root.right.left.right = new Node(7);
List<int> ans = DiagonalPrint(root);
PrintList(ans);
}
}
JavaScript
// JavaScript Program to print diagonal view
class Node {
constructor(x) {
this.key = x;
this.left = null;
this.right = null;
}
}
// Iterative function to print diagonal view
function diagonalPrint(root) {
let ans = [];
// base case
if (root === null)
return ans;
let q = [];
// push root
q.push(root);
while (q.length > 0) {
let curr = q.shift();
while (curr !== null) {
ans.push(curr.key);
// if left child is present
// push into queue
if (curr.left !== null)
q.push(curr.left);
// current equals to right child
curr = curr.right;
}
}
return ans;
}
function printList(v) {
for (let i = 0; i < v.length; i++) {
process.stdout.write(v[i] + " ");
}
console.log();
}
// Create a hard coded tree
// 8
// / \
// 3 10
// / / \
// 1 6 14
// / \ /
// 4 7 13
let root = new Node(8);
root.left = new Node(3);
root.right = new Node(10);
root.left.left = new Node(1);
root.right.left = new Node(6);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
root.right.left.left = new Node(4);
root.right.left.right = new Node(7);
let ans = diagonalPrint(root);
printList(ans);
Output8 10 14 3 6 7 13 1 4
Time Complexity: O(n), where n is the total number of nodes in the binary tree.
Auxiliary Space: O(n)
Related articles: