Reverse Level Order Traversal (original) (raw)

Given a binary tree, the task is to find its reverse level order traversal. The idea is to print the last level first, then the second last level, and so on. Like Level order traversal, every level is printed from **left to right.

**Examples:

**Input:

**Output:
_4 5
_2 3
_1

Table of Content

[Naive Approach] Using Recursion - O(n^2) Time and O(h) Space:

The algorithm for **reverse level order traversal involves printing nodes level by level, starting from the **bottom-most level and moving up to the **root. First, the **height of the tree is determined, denoted as **h. The traversal then begins from **level h and proceeds upwards to **level 1. In each iteration, **printGivenLevel function is called to print nodes at the **current level. It prints the node's data if the **current level matches the **required level. If not, the function **recursively explores the **left and **right subtrees to find and print nodes at the required level.

C++ `

// A recursive C++ program to print // reverse level order traversal #include <bits/stdc++.h> using namespace std;

class Node { public: int data; Node *left; Node *right; Node(int x) { data = x; left = right = nullptr; } };

// Function to find the height of // the tree. int height(Node *node) { if (node == nullptr) return 0;

int lheight = height(node->left);
int rheight = height(node->right);

return max(lheight, rheight) + 1;

}

// Print nodes at a given level void printGivenLevel(Node *root, int nodeLevel, int reqLevel) { if (root == nullptr) return;

// if the required level is reached,
// then print the node.
if (nodeLevel == reqLevel)
    cout << root->data << " ";

// else call function for left and
// right subtree.
else if (nodeLevel < reqLevel) {
    printGivenLevel(root->left, nodeLevel + 1, reqLevel);
    printGivenLevel(root->right, nodeLevel + 1, reqLevel);
}

}

// Function to print reverse // level order traversal a tree void reverseLevelOrder(Node *root) {

// find the height of the tree.
int h = height(root);

// Start printing from the lowest level.
for (int i = h; i >= 1; i--)
    printGivenLevel(root, 1, i);

}

int main() {

// create hard coded tree
//       1
//      / \
//     2   3
//    / \
//   4   5
Node *root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);

reverseLevelOrder(root);

return 0;

}

C

// A recursive C program to print // reverse level order traversal #include <stdio.h> #include <stdlib.h>

struct Node { int data; struct Node* left; struct Node* right; };

// Function to find the height of the tree. int height(struct Node* node) { if (node == NULL) return 0;

int lheight = height(node->left);
int rheight = height(node->right);

return (lheight > rheight ? lheight : rheight) + 1;

}

// Print nodes at a given level void printGivenLevel(struct Node* root, int nodeLevel, int reqLevel) { if (root == NULL) return;

// if the required level is reached,
// then print the node.
if (nodeLevel == reqLevel)
    printf("%d ", root->data);

// else call function for left and right subtree.
else if (nodeLevel < reqLevel) {
    printGivenLevel(root->left, nodeLevel + 1, reqLevel);
    printGivenLevel(root->right, nodeLevel + 1, reqLevel);
}

}

// Function to print REVERSE level order traversal of a tree void reverseLevelOrder(struct Node* root) {

// find the height of the tree.
int h = height(root);

// Start printing from the lowest level.
for (int i = h; i >= 1; i--)
    printGivenLevel(root, 1, i);

}

struct Node* createNode(int x) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = x; node->left = NULL; node->right = NULL; return node; }

int main() {

// create hard coded tree
//       1
//      / \
//     2   3
//    / \
//   4   5
struct Node* root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);

reverseLevelOrder(root);

return 0;

}

Java

// A recursive Java program to print // reverse level order traversal class Node { int data; Node left, right;

Node(int x) {
    data = x;
    left = right = null;
}

}

class GfG {

// Function to find the height of the tree.
static int height(Node node) {
    if (node == null)
        return 0;

    int lheight = height(node.left);
    int rheight = height(node.right);

    return Math.max(lheight, rheight) + 1;
}

// Print nodes at a given level
static void printGivenLevel(Node root, int nodeLevel, int reqLevel) {
    if (root == null)
        return;

    // if the required level is reached, print the node.
    if (nodeLevel == reqLevel)
        System.out.print(root.data + " ");

    // else call function for left and right subtree.
    else if (nodeLevel < reqLevel) {
        printGivenLevel(root.left, nodeLevel + 1, reqLevel);
        printGivenLevel(root.right, nodeLevel + 1, reqLevel);
    }
}

// Function to print REVERSE level order traversal of a tree
static void reverseLevelOrder(Node root) {
    // find the height of the tree.
    int h = height(root);

    // Start printing from the lowest level.
    for (int i = h; i >= 1; i--)
        printGivenLevel(root, 1, i);
}

public static void main(String[] args) {
  
    // create hard coded tree
    //       1
    //      / \
    //     2   3
    //    / \
    //   4   5
    Node root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);
    root.left.left = new Node(4);
    root.left.right = new Node(5);

    reverseLevelOrder(root);
}

}

Python

A recursive Python program to print

reverse level order traversal

class Node: def init(self, x): self.data = x self.left = None self.right = None

Function to find the height of the tree.

def height(node): if node is None: return 0

lheight = height(node.left)
rheight = height(node.right)

return max(lheight, rheight) + 1

Print nodes at a given level

def print_given_level(root, node_level, req_level): if root is None: return

# if the required level is reached, print the node.
if node_level == req_level:
    print(root.data, end=" ")

# else call function for left and right subtree.
elif node_level < req_level:
    print_given_level(root.left, node_level + 1, req_level)
    print_given_level(root.right, node_level + 1, req_level)

Function to print REVERSE level order traversal of a tree

def reverse_level_order(root):

# find the height of the tree.
h = height(root)

# Start printing from the lowest level.
for i in range(h, 0, -1):
    print_given_level(root, 1, i)

if name == "main":

# create hard coded tree
#       1
#      / \
#     2   3
#    / \
#   4   5
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)

reverse_level_order(root)

C#

// A recursive C# program to print // reverse level order traversal using System;

class Node { public int data; public Node left, right;

public Node(int x) {
    data = x;
    left = right = null;
}

}

class GfG {

// Function to find the height of the tree.
static int height(Node node) {
    if (node == null)
        return 0;

    int lheight = height(node.left);
    int rheight = height(node.right);

    return Math.Max(lheight, rheight) + 1;
}

// Print nodes at a given level
static void printGivenLevel(Node root, int nodeLevel, int reqLevel) {
    if (root == null)
        return;

    // if the required level is reached, print the node.
    if (nodeLevel == reqLevel)
        Console.Write(root.data + " ");

    // else call function for left and right subtree.
    else if (nodeLevel < reqLevel) {
        printGivenLevel(root.left, nodeLevel + 1, reqLevel);
        printGivenLevel(root.right, nodeLevel + 1, reqLevel);
    }
}

// Function to print REVERSE level order traversal of a tree
static void reverseLevelOrder(Node root) {
    
    // find the height of the tree.
    int h = height(root);

    // Start printing from the lowest level.
    for (int i = h; i >= 1; i--)
        printGivenLevel(root, 1, i);
}

static void Main() {
    
    // create hard coded tree
    //       1
    //      / \
    //     2   3
    //    / \
    //   4   5
    Node root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);
    root.left.left = new Node(4);
    root.left.right = new Node(5);

    reverseLevelOrder(root);
}

}

JavaScript

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

class Node { constructor(x) { this.data = x; this.left = null; this.right = null; } }

// Function to find the height of the tree. function height(node) { if (node === null) return 0;

let lheight = height(node.left);
let rheight = height(node.right);

return Math.max(lheight, rheight) + 1;

}

// Print nodes at a given level function printGivenLevel(root, nodeLevel, reqLevel) { if (root === null) return;

// if the required level is reached, print the node.
if (nodeLevel === reqLevel)
    console.log(root.data);

// else call function for left and right subtree.
else if (nodeLevel < reqLevel) {
    printGivenLevel(root.left, nodeLevel + 1, reqLevel);
    printGivenLevel(root.right, nodeLevel + 1, reqLevel);
}

}

// Function to print REVERSE level order traversal of a tree function reverseLevelOrder(root) {

// find the height of the tree.
let h = height(root);

// Start printing from the lowest level.
for (let i = h; i >= 1; i--)
    printGivenLevel(root, 1, i);

}

// create hard coded tree // 1 // /
// 2 3 // /
// 4 5 let root = new Node(1); root.left = new Node(2); root.right = new Node(3); root.left.left = new Node(4); root.left.right = new Node(5);

reverseLevelOrder(root);

`

**Time Complexity: O(n^2)
**Auxiliary Space: O(h), where h is the height of the tree.

[Expected Approach] Using Stack and Queue - O(n) Time and O(n) Space:

The approach for reverse level order traversal, using a **stack and **queue is conceptually similar to a standard level order traversal but with key modifications. Instead of **printing each node as it is **visited, the nodes are **pushed onto a **stack. Additionally, when **enqueueing children nodes, the **right child is **enqueued before the **left child. This ensures that when nodes are **popped from the **stack, they are printed in **reverse level order.

Step by step implementation:

  1. The idea is to use a **stack to get the **reverse level order.
  2. Push the root node into a **queue. While queue is not **empty, perform steps 3,4.
  3. Pop the **front element of the **queue. Instead of printing it (like in level order), **push node's value into a **stack. This way the elements present on **upper levels will be printed **later than elements on lower levels.
  4. If the right child of **current node exists, **push it into **queue before **left child. This is because elements on the same level should be printed from **left to right.
  5. While stack is not empty, **pop the **top element and print it. C++ `

// C++ program to print reverse level // order traversal using stack and queue #include <bits/stdc++.h> using namespace std;

class Node { public: int data; Node* left; Node* right; Node (int x) { data = x; left = right = nullptr; } };

// Function to print REVERSE // level order traversal of a tree void reverseLevelOrder(Node* root) { stack<Node*> st;
queue<Node*> q;
q.push(root);

while (!q.empty()) {
    // Dequeue node
    Node* curr = q.front();
    q.pop();
    st.push(curr);

    // Enqueue right child
    if (curr->right)
        q.push(curr->right);

    // Enqueue left child
    if (curr->left)
        q.push(curr->left);
}

// Pop all items from stack one by one and print them
while (!st.empty()) {
    Node* curr = st.top();
    cout << curr->data << " ";
    st.pop();
}

}

int main() {

// Create hard coded tree
//       1
//      / \
//     2   3
//    / \
//   4   5 
Node *root = new Node(1); 
root->left = new Node(2); 
root->right = new Node(3); 
root->left->left = new Node(4); 
root->left->right = new Node(5); 

reverseLevelOrder(root); 

return 0; 

}

Java

// Java program to print reverse level // order traversal using stack and queue import java.util.LinkedList; import java.util.Queue; import java.util.Stack;

class Node { int data; Node left, right;

Node(int x) {
    data = x;
    left = right = null;
}

}

class GfG {

// Function to print REVERSE level order traversal of a tree
static void reverseLevelOrder(Node root) {
    Stack<Node> st = new Stack<>();
    Queue<Node> q = new LinkedList<>();
    q.add(root);

    while (!q.isEmpty()) {
      
        // Dequeue node
        Node curr = q.poll();
        st.push(curr);

        // Enqueue right child
        if (curr.right != null)
            q.add(curr.right);

        // Enqueue left child
        if (curr.left != null)
            q.add(curr.left);
    }

    // Pop all items from stack one by one and print them
    while (!st.isEmpty()) {
        Node curr = st.pop();
        System.out.print(curr.data + " ");
    }
}

public static void main(String[] args) {
    
    // Create hard coded tree
    //       1
    //      / \
    //     2   3
    //    / \
    //   4   5
    Node root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);
    root.left.left = new Node(4);
    root.left.right = new Node(5);

    reverseLevelOrder(root);
}

}

Python

Python program to print reverse level

order traversal using stack and queue

from collections import deque

class Node: def init(self, x): self.data = x self.left = None self.right = None

Function to print REVERSE level order traversal of a tree

def reverse_level_order(root): st = [] q = deque([root])

while q:
  
    # Dequeue node
    curr = q.popleft()
    st.append(curr)

    # Enqueue right child
    if curr.right:
        q.append(curr.right)

    # Enqueue left child
    if curr.left:
        q.append(curr.left)

# Pop all items from stack one by one and print them
while st:
    curr = st.pop()
    print(curr.data, end=" ")

if name == "main":

# Create hard coded tree
#       1
#      / \
#     2   3
#    / \
#   4   5
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)

reverse_level_order(root)

C#

// C# program to print reverse level // order traversal using stack and queue using System; using System.Collections.Generic;

class Node { public int data; public Node left, right;

public Node(int x) {
    data = x;
    left = right = null;
}

}

class GfG {

// Function to print REVERSE level order traversal of a tree
static void ReverseLevelOrder(Node root) {
    Stack<Node> S = new Stack<Node>(); 
    Queue<Node> Q = new Queue<Node>(); 
    Q.Enqueue(root);

    while (Q.Count > 0) {
      
        // Dequeue node
        Node curr = Q.Dequeue();
        S.Push(curr);

        // Enqueue right child
        if (curr.right != null)
            Q.Enqueue(curr.right);

        // Enqueue left child
        if (curr.left != null)
            Q.Enqueue(curr.left);
    }

    // Pop all items from stack one by one and print them
    while (S.Count > 0) {
        Node curr = S.Pop();
        Console.Write(curr.data + " ");
    }
}

static void Main(string[] args) {
  
    // Create a hard coded tree
    //       1
    //      / \
    //     2   3
    //    / \
    //   4   5
    Node root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);
    root.left.left = new Node(4);
    root.left.right = new Node(5);

    ReverseLevelOrder(root);
}

}

JavaScript

// Javascript program to print reverse level // order traversal using stack and queue

class Node { constructor(x) { this.data = x; this.left = null; this.right = null; } }

// Function to print REVERSE level order traversal of a tree function reverseLevelOrder(root) { let S = []; let Q = []; Q.push(root);

while (Q.length > 0) {

    // Dequeue node
    let curr = Q.shift();
    S.push(curr);

    // Enqueue right child
    if (curr.right)
        Q.push(curr.right);

    // Enqueue left child
    if (curr.left)
        Q.push(curr.left);
}

// pop all items from stack one by one and print them
while (S.length > 0) {
    let curr = S.pop();
    console.log(curr.data);
}

}

// create hard coded tree // 1 // /
// 2 3 // /
// 4 5 let root = new Node(1); root.left = new Node(2); root.right = new Node(3); root.left.left = new Node(4); root.left.right = new Node(5);

reverseLevelOrder(root);

`

**Time Complexity: O(n), where **n is the number of nodes in the binary tree.
**Auxiliary Space: O(n)

[Alternate Approach] Using a hash map - O(n) Time and O(n) Space:

The approach to **reverse level order traversal using a **hash map involves storing nodes by their **levels and then retrieving them in reverse order. To achieve this, a hash map is used where each level of the binary tree maps to a list of nodes at that level. During a pre-order traversal of the tree, nodes are added to the hash map based on their level, ensuring that nodes are processed from the leftmost node at each level first. If the current node is **null, the function returns immediately. Otherwise, it adds the node to the list corresponding to its **level in the **hash map, then **recursively processes the **left and **right children.

After completing the traversal, the **height of the tree, denoted by the size of the hash map, determines the **number of levels. The final step is to iterate over the hash map from the **highest level down to level 1, printing nodes from each level to achieve the reverse level order traversal.

Below is the implementation of the above approach:

C++ `

//C++ program to print reverse level // order traversal using hashmap #include <bits/stdc++.h> using namespace std;

class Node { public: int data; Node* left; Node* right; Node (int x) { data = x; left = right = nullptr; } };

// Recursive function to traverse the binary // tree and add nodes to the hashmap void addNodesToMap(Node* node, int level, unordered_map<int, vector >& map) { if (node == nullptr) return;

// Add the current node to the vector of
// nodes at its level in the hashmap
map[level].push_back(node->data);

// Recursively traverse the left and
// right subtrees
addNodesToMap(node->left, level + 1, map);
addNodesToMap(node->right, level + 1, map);

}

vector reverseLevelOrder(Node* root) { vector result;

// Create an unordered_map to store the
// nodes at each level of the binary tree
unordered_map<int, vector<int> > map;

// Traverse the binary tree recursively and
// add nodes to the hashmap
addNodesToMap(root, 0, map);

// Iterate over the hashmap in reverse order of the
// levels and add nodes to the result vector
for (int level = map.size() - 1; level >= 0;
     level--) {
    vector<int> nodesAtLevel = map[level];
    for (int i = 0; i < nodesAtLevel.size(); i++) {
        result.push_back(nodesAtLevel[i]);
    }
}

return result;

}

void printList(vector v) { for (int i=0; i<v.size(); i++) { cout << v[i] << " "; } cout<<endl; }

int main() {

// create hard coded tree
//       1
//      / \
//     2   3
//    / \
//   4   5 
Node *root = new Node(1); 
root->left = new Node(2); 
root->right = new Node(3); 
root->left->left = new Node(4); 
root->left->right = new Node(5); 

vector<int> result = reverseLevelOrder(root); 

printList(result);

return 0; 

}

Java

// Java program to print reverse level // order traversal using hashmap import java.util.*;

class Node { int data; Node left, right;

Node(int x) {
    data = x;
    left = right = null;
}

}

class GfG {

// Recursive function to traverse the binary
// tree and add nodes to the hashmap
static void addNodesToMap(Node node, int level, Map<Integer, List<Integer>> map) {
    if (node == null)
        return;

    map.putIfAbsent(level, new ArrayList<>());
    map.get(level).add(node.data);

    // Recursively traverse the left and right subtrees
    addNodesToMap(node.left, level + 1, map);
    addNodesToMap(node.right, level + 1, map);
}

static List<Integer> reverseLevelOrder(Node root) {
    ArrayList<Integer> result = new ArrayList<>();

    // Create a HashMap to store the nodes 
      // at each level of the binary tree
    Map<Integer, List<Integer>> map = 
      new HashMap<>();

    // Traverse the binary tree recursively 
      // and add nodes to the hashmap
    addNodesToMap(root, 0, map);

    // Iterate over the hashmap in reverse 
      //order of the levels and add nodes 
      // to the result
    for (int level = map.size() - 1; 
         level >= 0; level--) {
        result.addAll(map.get(level));
    }

    return result;
}

public static void main(String[] args) {
    
    // create hard coded tree
    //       1
    //      / \
    //     2   3
    //    / \
    //   4   5
    Node root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);
    root.left.left = new Node(4);
    root.left.right = new Node(5);

    List<Integer> result = reverseLevelOrder(root);
    result.forEach(node -> System.out.print(node + " "));
}

}

Python

Python program to print REVERSE level

order traversal using hashmap

from collections import defaultdict

class Node: def init(self, x): self.data = x self.left = None self.right = None

Recursive function to traverse the binary tree

and add nodes to the hashmap

def add_nodes_to_map(node, level, map): if node is None: return

map[level].append(node.data)

# Recursively traverse the left and right subtrees
add_nodes_to_map(node.left, level + 1, map)
add_nodes_to_map(node.right, level + 1, map)

def reverse_level_order(root): result = []

# Create a defaultdict to store the nodes 
# at each level of the binary tree
map = defaultdict(list)

# Traverse the binary tree recursively 
# and add nodes to the hashmap
add_nodes_to_map(root, 0, map)

# Iterate over the hashmap in reverse order of 
# the levels and add nodes to the result
for level in reversed(range(len(map))):
    result.extend(map[level])

return result

def print_list(lst): print(" ".join(map(str, lst)))

if name == "main":

# create hard coded tree
#       1
#      / \
#     2   3
#    / \
#   4   5
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)

result = reverse_level_order(root)
print_list(result)

C#

// A C# program to print REVERSE level // order traversal using hashmap using System; using System.Collections.Generic;

class Node { public int data; public Node left, right;

public Node(int x) {
    data = x;
    left = right = null;
}

}

class GfG {

// Recursive function to traverse the binary tree
// and add nodes to the hashmap
static void AddNodesToMap(Node node, int level, Dictionary<int, List<int>> map) {
    if (node == null)
        return;

    if (!map.ContainsKey(level))
        map[level] = new List<int>();

    map[level].Add(node.data);

    // Recursively traverse the left and right subtrees
    AddNodesToMap(node.left, level + 1, map);
    AddNodesToMap(node.right, level + 1, map);
}

static List<int> ReverseLevelOrder(Node root) {
    List<int> result = new List<int>();

    // Create a Dictionary to store the 
      // nodes at each level of the binary tree
    Dictionary<int, List<int>> map = new Dictionary<int, List<int>>();

    // Traverse the binary tree recursively 
      // and add nodes to the hashmap
    AddNodesToMap(root, 0, map);

    // Iterate over the hashmap in reverse order
      // of the levels and add nodes to the result
    for (int level = map.Count - 1; level >= 0; level--) {
        result.AddRange(map[level]);
    }

    return result;
}

static void PrintList(List<int> list) {
    foreach (var item in list) {
        Console.Write(item + " ");
    }
    Console.WriteLine();
}

static void Main(string[] args) {
    
    // create hard coded tree
    //       1
    //      / \
    //     2   3
    //    / \
    //   4   5
    Node root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);
    root.left.left = new Node(4);
    root.left.right = new Node(5);

    List<int> result = ReverseLevelOrder(root);
    PrintList(result);
}

}

JavaScript

// JavaScript program to print REVERSE level // order traversal using hashmap class Node { constructor(x) { this.data = x; this.left = null; this.right = null; } }

// Recursive function to traverse the binary tree // and add nodes to the hashmap function addNodesToMap(node, level, map) { if (node === null) return;

if (!map.has(level)) map.set(level, []);
map.get(level).push(node.data);

// Recursively traverse the left and right subtrees
addNodesToMap(node.left, level + 1, map);
addNodesToMap(node.right, level + 1, map);

}

function reverseLevelOrder(root) { const result = []; const map = new Map();

// Traverse the binary tree recursively 
// and add nodes to the hashmap
addNodesToMap(root, 0, map);

// Iterate over the hashmap in reverse order 
// of the levels and add nodes to the result
for (let level = map.size - 1; level >= 0; level--) {
    result.push(...map.get(level));
}

return result;

}

function printList(list) { console.log(list.join(" ")); }

const root = new Node(1); root.left = new Node(2); root.right = new Node(3); root.left.left = new Node(4); root.left.right = new Node(5);

const result = reverseLevelOrder(root); printList(result);

`

**Time complexity: O(n), where **n is the number of nodes in the binary tree.
**Auxiliary Space: O(n)