Open In App

Connect Nodes at same Level (Level Order Traversal)

Last Updated : 04 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a binary tree, the task is to connect the nodes that are at the same level. Given an addition nextRight pointer for the same. Initially, all the next right pointers point to garbage values, set these pointers to the point next right for each node.

Example: 

Input:

Connect-Nodes-at-same-Level-2-

Output:

Connect-Nodes-at-same-Level-


Explanation:  The above tree represents the nextRight pointer connected the nodes that are at the same level.

Approach:

This idea is to use level order traversal to connect nodes at the same level. A NULL is pushed after each level to track the end of the level. As nodes are processed, each node's nextRight pointer is set to the next node in the queue. If a NULL is encountered and the queue isn't empty, another NULL is added to mark the end of the next level. This ensures that all nodes at the same level are linked.

Step-By-Step Implementation:

  • Initialize a queue to store the nodes of the binary tree, starting with the root node, followed by a null marker to represent the end of the first level
  • Perform a level order traversal by popping nodes from the queue. For each node, link it to the next node in the queue (the next node at the same level).
  • Push the left and right children of the current node into the queue.
  • When a null is encountered, it represents the end of the level. If the queue is not empty, push another null to indicate the end of the next level.
  • Continue this process until all nodes have been processed and linked to their next right neighbors.

Below is the implementation of the above approach:

C++
// C++ Program to Connect Nodes at same Level

#include <bits/stdc++.h>

using namespace std;

class Node {
  public:
    int data;
    Node *left;
    Node *right;
    Node *nextRight;

    Node(int key) {
        data = key;
        left = nullptr;
        right = nullptr;
        nextRight = nullptr;
    }
};

// Sets nextRight of all nodes of a tree
Node *connect(Node *root) {
    if (!root)
        return root;

    queue<Node *> q;
    q.push(root);
    q.push(nullptr);

    while (!q.empty()) {
        Node *node = q.front();
        q.pop();

        if (node != nullptr) {

            // next element in queue represents the next
            // node at the current level
            node->nextRight = q.front();

            // Push left and right children of the
            // current node
            if (node->left)
                q.push(node->left);
            if (node->right)
                q.push(node->right);
        }
        else if (!q.empty()) {
            q.push(nullptr);
        }
    }

    return root;
}

// Function to store the nextRight pointers in level-order
// format and return as a vector
vector<string> getNextRightVector(Node *root) {
    vector<string> result;
    if (!root)
        return result;

    queue<Node *> q;
    q.push(root);
    q.push(nullptr);

    while (!q.empty()) {
        Node *node = q.front();
        q.pop();

        if (node) {
            result.push_back(to_string(node->data));

            if (node->nextRight == nullptr) {
                result.push_back("#");
            }

            // Push the left and right children 
          	// (next level nodes)
            if (node->left) {
                q.push(node->left);
            }
            if (node->right) {
                q.push(node->right);
            }
        }
        else if (!q.empty()) {

            // Level delimiter: push another
          	// delimiter to the queue
            q.push(nullptr);
        }
    }

    return result;
}

int main() {

    // Constructed binary tree is
    //       10
    //      /  \
    //    8     2
    //   /        \
    //  3          90

    Node *root = new Node(10);
    root->left = new Node(8);
    root->right = new Node(2);
    root->left->left = new Node(3);
    root->right->right = new Node(90);

    connect(root);
  
    vector<string> output = getNextRightVector(root);

    for (string s : output) {
        cout << s << ' ';
    }
    cout << endl;

    return 0;
}
Java
// Java Program to Connect Nodes at same Level

import java.util.*;

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

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

class GfG {

    // Sets nextRight of all nodes of a tree
    static Node connect(Node root) {
        if (root == null)
            return root;

        Queue<Node> q = new LinkedList<>();
        q.add(root);
        q.add(null);

        while (!q.isEmpty()) {
            Node node = q.poll();

            if (node != null) {

                // next element in queue represents the next
                // node at the current level
                node.nextRight = q.peek();

                // Push left and right children of the
                // current node
                if (node.left != null)
                    q.add(node.left);
                if (node.right != null)
                    q.add(node.right);
            }
            else if (!q.isEmpty()) {
                q.add(null);
            }
        }

        return root;
    }

    // Function to store the nextRight pointers in
    // level-order format and return as a List
    static List<String> getNextRightList(Node root) {
        List<String> result = new ArrayList<>();
        if (root == null)
            return result;

        Queue<Node> q = new LinkedList<>();
        q.add(root);
        q.add(null);

        while (!q.isEmpty()) {
            Node node = q.poll();

            if (node != null) {
                result.add(Integer.toString(node.data));

                if (node.nextRight == null) {
                    result.add("#");
                }

                // Push the left and right children (next
                // level nodes)
                if (node.left != null)
                    q.add(node.left);
                if (node.right != null)
                    q.add(node.right);
            }
            else if (!q.isEmpty()) {

                // Level delimiter: push another delimiter
                // to the queue
                q.add(null);
            }
        }

        return result;
    }

    public static void main(String[] args) {

        // Constructed binary tree is
        //       10
        //      /  \
        //    8     2
        //   /        \
        //  3          90

        Node root = new Node(10);
        root.left = new Node(8);
        root.right = new Node(2);
        root.left.left = new Node(3);
        root.right.right = new Node(90);

        connect(root);

        List<String> output = getNextRightList(root);
        System.out.println(String.join(" ", output));
    }
}
Python
# Python Program to Connect Nodes at same Level

class Node:
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
        self.nextRight = None

# Sets nextRight of all nodes of a tree
def connect(root):
    if not root:
        return root

    q = []
    q.append(root)
    q.append(None)

    while q:
        node = q.pop(0)

        if node:
          
            # next element in queue represents the next
            # node at the current level
            node.nextRight = q[0]

            # Push left and right children of the
            # current node
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)
        elif q:
            q.append(None)

    return root

# Function to store the nextRight pointers in level-order
# format and return as a list
def getNextRightList(root):
    result = []
    if not root:
        return result

    q = []
    q.append(root)
    q.append(None)

    while q:
        node = q.pop(0)

        if node:
            result.append(str(node.data))

            if node.nextRight is None:
                result.append("#")

            # Push the left and right children (next level nodes)
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)
        elif q:

            # Level delimiter: push another delimiter to the queue
            q.append(None)

    return result

if __name__ == "__main__":
  
    # Constructed binary tree is
    #       10
    #      /  \
    #    8     2
    #   /        \
    #  3          90

    root = Node(10)
    root.left = Node(8)
    root.right = Node(2)
    root.left.left = Node(3)
    root.right.right = Node(90)

    connect(root)

    output = getNextRightList(root)
    print(" ".join(output))
C#
// C# Program to Connect Nodes at same Level

using System;
using System.Collections.Generic;

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

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

class GfG {

    // Sets nextRight of all nodes of a tree
    static Node Connect(Node root) {
        if (root == null)
            return root;

        Queue<Node> q = new Queue<Node>();
        q.Enqueue(root);
        q.Enqueue(null);

        while (q.Count > 0) {
            Node node = q.Dequeue();

            if (node != null) {

                // next element in queue represents the next
                // node at the current level
                node.nextRight
                    = q.Count > 0 ? q.Peek() : null;

                // Push left and right children of the
                // current node
                if (node.left != null)
                    q.Enqueue(node.left);
                if (node.right != null)
                    q.Enqueue(node.right);
            }
            else if (q.Count > 0) {
                q.Enqueue(null);
            }
        }

        return root;
    }

    // Function to store the nextRight pointers in
    // level-order format and return as a List
    static List<string> GetNextRightList(Node root) {
        List<string> result = new List<string>();
        if (root == null)
            return result;

        Queue<Node> q = new Queue<Node>();
        q.Enqueue(root);
        q.Enqueue(null);

        while (q.Count > 0) {
            Node node = q.Dequeue();

            if (node != null) {
                result.Add(node.data.ToString());

                if (node.nextRight == null) {
                    result.Add("#");
                }

                // Push the left and right children (next
                // level nodes)
                if (node.left != null)
                    q.Enqueue(node.left);
                if (node.right != null)
                    q.Enqueue(node.right);
            }
            else if (q.Count > 0) {

                // Level delimiter: push another delimiter
                // to the queue
                q.Enqueue(null);
            }
        }

        return result;
    }

    static void Main(string[] args) {

        // Constructed binary tree is
        //       10
        //      /  \
        //    8     2
        //   /        \
        //  3          90

        Node root = new Node(10);
        root.left = new Node(8);
        root.right = new Node(2);
        root.left.left = new Node(3);
        root.right.right = new Node(90);

        Connect(root);

        List<string> output = GetNextRightList(root);
        Console.WriteLine(string.Join(" ", output));
    }
}
JavaScript
// JavaScript Program to Connect Nodes at same Level

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

// Sets nextRight of all nodes of a tree
function connect(root) {
    if (!root)
        return root;

    let q = [];
    q.push(root);
    q.push(null);

    while (q.length > 0) {
        let node = q.shift();

        if (node !== null) {

            // next element in queue represents the next
            // node at the current level
            node.nextRight = q[0];

            // Push left and right children of the
            // current node
            if (node.left)
                q.push(node.left);
            if (node.right)
                q.push(node.right);
        }
        else if (q.length > 0) {
            q.push(null);
        }
    }

    return root;
}

// Function to store the nextRight pointers in level-order
// format and return as an array
function getNextRightArray(root) {
    let result = [];
    if (!root)
        return result;

    let q = [];
    q.push(root);
    q.push(null);

    while (q.length > 0) {
        let node = q.shift();

        if (node) {
            result.push(node.data.toString());

            if (node.nextRight === null) {
                result.push("#");
            }

            // Push the left and right children (next level
            // nodes)
            if (node.left)
                q.push(node.left);
            if (node.right)
                q.push(node.right);
        }
        else if (q.length > 0) {

            // Level delimiter: push another delimiter to
            // the queue
            q.push(null);
        }
    }

    return result;
}

// Constructed binary tree is
//       10
//      /  \
//    8     2
//   /        \
//  3          90

let root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
root.right.right = new Node(90);

connect(root);

let output = getNextRightArray(root);
console.log(output.join(" "));

Output
10 # 8 2 # 3 90 # 

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

Related articles:


Next Article

Similar Reads