Monday, November 18, 2024
Google search engine
HomeData Modelling & AIBottom-left to upward-right Traversal in a Binary Tree

Bottom-left to upward-right Traversal in a Binary Tree

Given a Binary Tree, the task is to print the Bottom-left to Upward-right Traversal of the given Binary Tree i.e., the level order traversal having level as Bottom-left to Upward-right node.

Examples:

Input: Below is the given Tree:

Output: 2 7 2 5 6 5 11 4 9
Explanation:
 Level 1: 2 7 2 (going upwards from bottom left to right to root) 
Level 2: 5 6 5 (right from each node in layer 1/or bottom left to upwards right in this layer)
Level 3: 11 4 9 (right from each node in layer 2/or bottom left to upwards right in this layer) 

Input: 1 2 3 4 5 6 7
Output: 4 2 1 5 6 3 2

Explanation
Layer 1: 4 2 1 (going upwards from bottom left to right to root)
Layer 2: 5 6 3 (right from each node in layer 1/or bottom left to upwards right in this layer)
Layer 3: 2 (right from each node in layer 2/or bottom left to upwards right in this layer)

Approach: The idea is to use the Breadth-First Search technique. Follow the steps needed to solve this problem:

  • Initialize a layer in a binary tree. It is a list of nodes starting from the bottom-left most node next to the previous layer and ends with the upper-right most node next to the previous layer.
  • Create a stack to stores all nodes in every layer.
  • Initialize a queue to maintain “roots” in each layer, a root in a layer is a node from which one may go downwards using left children only.
  • Push the root node of the first layer (the tree root) in the queue.
  • Define an indicator (say lyr_root) a node expected at the end of a layer which is the current layer head, a layer head is the first node in a layer.
  • Traverse until the queue is nonempty and do the following:
    • Get a layer root from the front of the queue
    • If this layer root is the layer head of a new layer, then, pop every element in the stack i.e., of the previous layer element, and print it.
    • Traverse the layer from the upper-right to the bottom-left and for each element, if it has a right child, then check if the traversed node is the layer head or not. If found to be true then, change the expected indicator to indicate to the next layer head.
    • Push the right child to the root in the queue.
    • Push the traversed node in the stack.
  • After traversing all the layers, the final layer may still be in the stack, so we need to pop every element from it and print it.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
// Node Structures
typedef struct Node {
    int data;
    Node* left;
    Node* right;
} Node;
 
// Function to add the new Node in
// the Binary Tree
Node* newNode(int data)
{
    Node* n;
 
    // Create a new Node
    n = new Node();
    n->data = data;
    n->right = NULL;
    n->left = NULL;
    return n;
}
 
// Function to traverse the tree in the
// order of bottom left to the upward
// right order
vector<int>
leftBottomTopRightTraversal(Node* root)
{
    // Stores the data of the node
    vector<int> rr;
 
    // Stores every element in each layer
    stack<int> r;
 
    // Stores the roots in the layers
    queue<Node*> roots;
 
    // Push the layer head of the
    // first layer
    roots.push(root);
 
    // Define the first layer head
    // as the tree root
    Node* lyr_root = root;
 
    // Traverse all layers
    while (!roots.empty()) {
 
        // get current layer root
        Node* n = roots.front();
 
        // Pop element from roots
        roots.pop();
        if (lyr_root == n) {
 
            // Layer root was also
            // the layer head
            while (!r.empty()) {
 
                rr.push_back(r.top());
 
                // Pop every element
                // from the stack
                r.pop();
            }
        }
 
        while (n) {
 
            if (n->right) {
 
                // Current traversed node
                // has right child then
                // this root is next layer
                if (n == lyr_root) {
                    lyr_root = n->right;
                }
 
                // Push the right child
                // to layer roots queue
                roots.push(n->right);
            }
 
            // Push node to the
            // layer stack
            r.push(n->data);
            n = n->left;
        }
    }
 
    // Insert all remaining elements
    // for the traversal
    while (!r.empty()) {
 
        // After all of the layer
        // roots traversed check the
        // final layer in stack
        rr.push_back(r.top());
        r.pop();
    }
 
    // Return the traversal of nodes
    return rr;
}
 
// Function that builds the binary tree
// from the given string
Node* buildBinaryTree(char* t)
{
    Node* root = NULL;
 
    // Using queue to build tree
    queue<Node**> q;
    int data = 0;
 
    // Stores the status of last
    // node to be ignored or not
    bool ignore_last = false;
    while (*t != '\0') {
        int d = *t - '0';
 
        // If the current character
        // is a digits then form the
        // number of it
        if (d >= 0 && d <= 9) {
            data *= 10;
            data += d;
            ignore_last = false;
        }
 
        // If the current character
        // is N then it is the
        // NULL node
        else if (*t == 'N') {
            data = 0;
            q.pop();
            ignore_last = true;
        }
 
        // If space occurred then
        // add the number formed
        else if (*t == ' ') {
 
            // If last is ignored
            if (!ignore_last) {
 
                // If root node is not NULL
                if (root) {
 
                    Node** p = q.front();
                    q.pop();
 
                    if (p != NULL) {
                        *p = newNode(data);
                        q.push(&((*p)->left));
                        q.push(&((*p)->right));
                    }
                }
 
                // Else create a new
                // root node
                else {
                    root = newNode(data);
                    q.push(&(root->left));
                    q.push(&(root->right));
                }
                data = 0;
            }
        }
 
        // Increment t
        t++;
    }
 
    // Return the root node of the tree
    return root;
}
 
// Driver Code
int main()
{
    // Given order of nodes
    char T[] = "2 7 5 2 6 N 9 N N 5 11 4 N";
 
    // Builds the Binary Tree
    Node* root = buildBinaryTree(T);
 
    // Function Call
    vector<int> result
        = leftBottomTopRightTraversal(root);
 
    // Print the final traversal
    for (int i = 0; i < result.size(); ++i) {
        cout << result[i] << " ";
    }
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
// Node Class
class Node {
    int data;
    Node left, right;
     
    Node(int data) {
        this.data = data;
        left = right = null;
    }
}
 
class Main {
    // Function to add the new Node in
    // the Binary Tree
    static Node newNode(int data) {
        // Create a new Node
        Node n = new Node(data);
        n.right = null;
        n.left = null;
        return n;
    }
    // Function to traverse the tree in the
    // order of bottom left to the upward
    // right order
    static List<Integer> leftBottomTopRightTraversal(Node root) {
         
        // Stores the data of the node
        List<Integer> rr = new ArrayList<>();
         
        // Stores every element in each layer
        Stack<Integer> r = new Stack<>();
         
        // Stores the roots in the layers
        Queue<Node> roots = new LinkedList<>();
         
         
        // Push the layer head of the
        // first layer
        roots.add(root);
         
         
        // Define the first layer head
        // as the tree root
        Node lyr_root = root;
         
        // Traverse all layers
        while (!roots.isEmpty()) {
             
            // get current layer root and will remove
            // the element from the root
            Node n = roots.poll();
 
            if (lyr_root == n) {
                 
                // Layer root was also
                // the layer head
                while (!r.empty()) {
                    rr.add(r.peek());
                    // Pop every element
                    // from the stack
                    r.pop();
                }
            }
 
            while (n != null) {
                if (n.right != null) {
                     
                    // Current traversed node
                    // has right child then
                    // this root is next layer
                    if (n == lyr_root) {
                        lyr_root = n.right;
                    }
                     
                     
                    // Push the right child
                    // to layer roots queue
                    roots.add(n.right);
                }
                 
                // Push node to the
                // layer stack
                r.push(n.data);
                n = n.left;
            }
        }
         
        // Insert all remaining elements
        // for the traversal
        while (!r.empty()) {
            // After all of the layer
            // roots traversed check the
            // final layer in stack
            rr.add(r.peek());
            r.pop();
        }
     
     
        // Return the traversal of nodes
        return rr;
    }
     
         
    // Function that builds the binary tree
    // from the given string
    public static Node buildBinaryTree(String input) {
        if (input == null || input.isEmpty()) {
            return null;
        }
         
        String[] values = input.trim().split("\\s+");
        if (values.length == 0) {
            return null;
        }
         
        Node root = new Node(Integer.parseInt(values[0]));
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
         
        for (int i = 1; i < values.length; i += 2) {
            Node parent = queue.poll();
             
            if (!values[i].equals("N")) {
                Node left = new Node(Integer.parseInt(values[i]));
                parent.left = left;
                queue.offer(left);
            }
             
            if (i + 1 < values.length && !values[i+1].equals("N")) {
                Node right = new Node(Integer.parseInt(values[i+1]));
                parent.right = right;
                queue.offer(right);
            }
        }
         
        return root;
    }
 
     
    // Driver Code
    public static void main(String[] args) {
         
        // Given order of nodes
        String T = "2 7 5 2 6 N 9 N N 5 11 4 N";
         
        // Builds the Binary Tree
        Node root = buildBinaryTree(T);
         
        // Function Call
        List<Integer> result = leftBottomTopRightTraversal(root);
         
        // Print the Final Traversal
        for (int i = 0; i < result.size(); i++) {
            System.out.print(result.get(i) + " ");
        }
    }
}
 
 
// This code is contributed by rishabmalhdijo


Python3




# Python program for the above approach
 
# Node Class
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Function to add the new Node in
# the Binary Tree
def newNode(data):
    # Create a new Node
    n = Node(data)
    n.right = None
    n.left = None
    return n
 
# Function to traverse the tree in the
# order of bottom left to the upward
# right order
def leftBottomTopRightTraversal(root):
    # Stores the data of the node
    rr = []
    # Stores every element in each layer
    r = []
    # Stores the roots in the layers
    roots = []
 
    # Push the layer head of the
    # first layer
    roots.append(root)
 
    # Define the first layer head
    # as the tree root
    lyr_root = root
 
    # Traverse all layers
    while roots:
        # get current layer root and will remove
        # the element from the root
        n = roots.pop(0)
 
        if lyr_root == n:
            # Layer root was also
            # the layer head
            while r:
                rr.append(r[-1])
                # Pop every element
                # from the stack
                r.pop()
 
        while n:
            if n.right:
                # Current traversed node
                # has right child then
                # this root is next layer
                if n == lyr_root:
                    lyr_root = n.right
 
                # Push the right child
                # to layer roots queue
                roots.append(n.right)
 
            # Push node to the
            # layer stack
            r.append(n.data)
            n = n.left
 
    # Insert all remaining elements
    # for the traversal
    while r:
        # After all of the layer
        # roots traversed check the
        # final layer in stack
        rr.append(r[-1])
        r.pop()
 
    # Return the traversal of nodes
    return rr
 
# Function that builds the binary tree
# from the given string
def buildBinaryTree(input):
    if input is None or input == '':
        return None
 
    values = input.strip().split()
    if not values:
        return None
 
    root = Node(int(values[0]))
    queue = []
    queue.append(root)
 
    for i in range(1, len(values), 2):
        parent = queue.pop(0)
 
        if values[i] != 'N':
            left = Node(int(values[i]))
            parent.left = left
            queue.append(left)
 
        if i + 1 < len(values) and values[i+1] != 'N':
            right = Node(int(values[i+1]))
            parent.right = right
            queue.append(right)
 
    return root
 
# Driver Code
if __name__ == '__main__':
    # Given order of nodes
    T = "2 7 5 2 6 N 9 N N 5 11 4 N"
 
    # Builds the Binary Tree
    root = buildBinaryTree(T)
 
    # Function Call
    result = leftBottomTopRightTraversal(root)
 
    # Print the Final Traversal
    for i in range(len(result)):
        print(result[i], end=' ')
 
 
 
# This code is contributed by Prince Kumar


C#




// C# code implementation
 
using System;
using System.Collections.Generic;
 
// Node Class
public class Node {
    public int data;
    public Node left, right;
     
    public Node(int data) {
        this.data = data;
        left = right = null;
    }
}
 
class MainClass {
    // Function to add the new Node in
    // the Binary Tree
    static Node newNode(int data) {
        // Create a new Node
        Node n = new Node(data);
        n.right = null;
        n.left = null;
        return n;
    }
    // Function to traverse the tree in the
    // order of bottom left to the upward
    // right order
    static List<int> leftBottomTopRightTraversal(Node root) {
         
        // Stores the data of the node
        List<int> rr = new List<int>();
         
        // Stores every element in each layer
        Stack<int> r = new Stack<int>();
         
        // Stores the roots in the layers
        Queue<Node> roots = new Queue<Node>();
         
         
        // Push the layer head of the
        // first layer
        roots.Enqueue(root);
         
         
        // Define the first layer head
        // as the tree root
        Node lyr_root = root;
         
        // Traverse all layers
        while (roots.Count > 0) {
             
            // get current layer root and will remove
            // the element from the root
            Node n = roots.Dequeue();
 
            if (lyr_root == n) {
                 
                // Layer root was also
                // the layer head
                while (r.Count > 0) {
                    rr.Add(r.Peek());
                    // Pop every element
                    // from the stack
                    r.Pop();
                }
            }
 
            while (n != null) {
                if (n.right != null) {
                     
                    // Current traversed node
                    // has right child then
                    // this root is next layer
                    if (n == lyr_root) {
                        lyr_root = n.right;
                    }
                     
                     
                    // Push the right child
                    // to layer roots queue
                    roots.Enqueue(n.right);
                }
                 
                // Push node to the
                // layer stack
                r.Push(n.data);
                n = n.left;
            }
        }
         
        // Insert all remaining elements
        // for the traversal
        while (r.Count > 0) {
            // After all of the layer
            // roots traversed check the
            // final layer in stack
            rr.Add(r.Peek());
            r.Pop();
        }
     
     
        // Return the traversal of nodes
        return rr;
    }
     
         
    // Function that builds the binary tree
    // from the given string
    public static Node buildBinaryTree(string input) {
        if (input == null || input.Length == 0) {
            return null;
        }
         
        string[] values = input.Trim().Split(' ');
        if (values.Length == 0) {
            return null;
        }
         
        Node root = new Node(int.Parse(values[0]));
        Queue<Node> queue = new Queue<Node>();
        queue.Enqueue(root);
         
        for (int i = 1; i < values.Length; i += 2) {
            Node parent = queue.Dequeue();
             
            if (!values[i].Equals("N")) {
                Node left = new Node(int.Parse(values[i]));
                parent.left = left;
                queue.Enqueue(left);
            }
             
            if (i + 1 < values.Length && !values[i+1].Equals("N")) {
                Node right = new Node(int.Parse(values[i+1]));
                parent.right = right;
                queue.Enqueue(right);
            }
        }
         
        return root;
    }
 
     
    // Driver Code
    static void Main() {
         
        // Given order of nodes
        string T = "2 7 5 2 6 N 9 N N 5 11 4 N";
         
        // Builds the Binary Tree
        Node root = buildBinaryTree(T);
         
        // Function Call
        List<int> result = leftBottomTopRightTraversal(root);
         
        // Print the Final Traversal
        for (int i = 0; i < result.Count; i++) {
            Console.Write(result[i] + " ");
        }
    }
}
 
// The code is contributed by Nidhi goel.


Javascript




// Node Class
class Node {
    constructor(data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}
 
// Function to add the new Node in
// the Binary Tree
function newNode(data) {
    // Create a new Node
    let n = new Node(data);
    n.right = null;
    n.left = null;
    return n;
}
 
// Function to traverse the tree in the
// order of bottom left to the upward
// right order
function leftBottomTopRightTraversal(root) {
    // Stores the data of the node
    let rr = [];
    // Stores every element in each layer
    let r = [];
    // Stores the roots in the layers
    let roots = [];
 
    // Push the layer head of the
    // first layer
    roots.push(root);
 
    // Define the first layer head
    // as the tree root
    let lyr_root = root;
 
    // Traverse all layers
    while (roots.length > 0) {
        // get current layer root and will remove
        // the element from the root
        let n = roots.shift();
        if (lyr_root == n) {
            // Layer root was also
            // the layer head
            while (r.length > 0) {
                rr.push(r[r.length - 1]);
                // Pop every element
                // from the stack
                r.pop();
            }
        }
 
        while (n != null) {
            if (n.right != null) {
                // Current traversed node
                // has right child then
                // this root is next layer
                if (n == lyr_root) {
                    lyr_root = n.right;
                }
 
                // Push the right child
                // to layer roots queue
                roots.push(n.right);
            }
 
            // Push node to the
            // layer stack
            r.push(n.data);
            n = n.left;
        }
    }
 
    // Insert all remaining elements
    // for the traversal
    while (r.length > 0) {
        // After all of the layer
        // roots traversed check the
        // final layer in stack
        rr.push(r[r.length - 1]);
        r.pop();
    }
 
    // Return the traversal of nodes
    return rr;
}
 
// Function that builds the binary tree
// from the given string
function buildBinaryTree(input) {
    if (input == null || input == "") {
        return null;
    }
 
    let values = input.trim().split(" ");
    if (values.length == 0) {
        return null;
    }
 
    let root = new Node(parseInt(values[0]));
    let queue = [];
    queue.push(root);
 
    for (let i = 1; i < values.length; i += 2) {
        let parent = queue.shift();
 
        if (values[i] != "N") {
            let left = new Node(parseInt(values[i]));
            parent.left = left;
            queue.push(left);
        }
 
        if (i + 1 < values.length && values[i + 1] != "N") {
            let right = new Node(parseInt(values[i + 1]));
            parent.right = right;
            queue.push(right);
        }
    }
 
    return root;
}
 
// Driver Code
let T = "2 7 5 2 6 N 9 N N 5 11 4 N";
 
// Builds the Binary Tree
let root = buildBinaryTree(T);
 
// Function Call
let result = leftBottomTopRightTraversal(root);
 
// Print the Final Traversal
console.log(result.join(" "))


Output: 

2 7 2 5 6 5 11 4 9

 

Time Complexity: O(N)
Auxiliary Space: O(N)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments