Populate Inorder Successor for all nodes

Last Updated : 26 Apr, 2026

Given a Binary Tree, complete the function to populate the next pointer for all nodes. The next pointer for every node should point to the Inorder successor of the node.

Note: The node having no in-order successor will be pointed to -1.

Example:

Input:

2056957815
Binary Tree

Output: 3->8 8->10 10->12 12->-1
Explanation: The inorder of the above tree is : 3 8 10 12. So the next pointer of node 3 is pointing to 8 , next pointer of 8 is pointing to 10 and so on and next pointer of 12 is pointing to -1 as there is no inorder successor of 12.

Input:

2056957816

Output: 3->2 2->1 1->-1
Explanation: The inorder of the above tree is: 3 2 1. So the next pointer of node 3 is pointing to 2 , next pointer of 2 is pointing to 1. And next pointer of 1 is pointing to -1 as there is no inorder successor of 1..

Try It Yourself
redirect icon

[Naive Approach] Storing Inorder - O(n) Time and O(n)

The intuition is to perform an inorder traversal of the binary tree because inorder naturally gives nodes in the order of their successors

  • Do Inorder traversal and store it in an array.
  • Traverse the array and connect every node with next to it in the array.
C++
#include <iostream>
#include <vector>

using namespace std;

// Node structure
struct Node
{
    int data;
    Node *left;
    Node *right;
    Node *next;

    Node(int val)
    {
        data = val;
        left = right = next = NULL;
    }
};

// Inorder traversal to store nodes
void inorder(Node *root, vector<Node *> &nodes)
{
    if (root == NULL)
        return;

    inorder(root->left, nodes);
    nodes.push_back(root);
    inorder(root->right, nodes);
}

// Function to populate next pointers
void populateNext(Node *root)
{
    vector<Node *> nodes;

    // Step 1: Store inorder traversal
    inorder(root, nodes);

    // Step 2: Link nodes
    int n = nodes.size();
    for (int i = 0; i < n - 1; i++)
    {
        nodes[i]->next = nodes[i + 1];
    }

    // Step 3: Last node points to NULL
    if (n > 0)
        nodes[n - 1]->next = NULL;
}

// Main function
int main()
{
    Node *root = new Node(10);

    root->left = new Node(8);
    root->right = new Node(12);

    root->left->left = new Node(3);

    // Populate next pointers
    populateNext(root);

    // Print result
    if (root == NULL)
        return 0;

    vector<Node *> nodes;
    inorder(root, nodes);

    for (int i = 0; i < nodes.size(); i++)
    {
        cout << nodes[i]->data << "->";
        if (nodes[i]->next)
            cout << nodes[i]->next->data << " ";
        else
            cout << "-1 ";
    }

    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>

// Node structure
struct Node
{
    int data;
    struct Node* left;
    struct Node* right;
    struct Node* next;
};

// Create new node
struct Node* newNode(int val)
{
    struct Node* node = (struct Node*)malloc(sizeof(struct Node));
    node->data = val;
    node->left = node->right = node->next = NULL;
    return node;
}

// Inorder traversal to store nodes
void inorder(struct Node* root, struct Node* nodes[], int* index)
{
    if (root == NULL)
        return;

    inorder(root->left, nodes, index);
    nodes[(*index)++] = root;
    inorder(root->right, nodes, index);
}

// Function to populate next pointers
void populateNext(struct Node* root)
{
    
    // assuming max 100 nodes
    struct Node* nodes[100]; 
    int index = 0;

    // Step 1: Store inorder traversal
    inorder(root, nodes, &index);

    // Step 2: Link nodes
    for (int i = 0; i < index - 1; i++)
    {
        nodes[i]->next = nodes[i + 1];
    }

    // Step 3: Last node points to NULL
    if (index > 0)
        nodes[index - 1]->next = NULL;
}

int main()
{
    struct Node* root = newNode(10);
    root->left = newNode(8);
    root->right = newNode(12);
    root->left->left = newNode(3);

    // Populate next pointers
    populateNext(root);
    
    // Print result
    struct Node* nodes[100];
    int index = 0;
    inorder(root, nodes, &index);
    for (int i = 0; i < index; i++)
    {
        printf("%d->", nodes[i]->data);
        if (nodes[i]->next)
            printf("%d ", nodes[i]->next->data);
        else
            printf("-1 ");
    }

    return 0;
}
Java
import java.util.*;

// Node structure
class Node {
    int data;
    Node left, right, next;

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

public class GfG {

    // Inorder traversal to store nodes
    static void inorder(Node root, List<Node> nodes) {
        if (root == null)
            return;

        inorder(root.left, nodes);
        nodes.add(root);
        inorder(root.right, nodes);
    }

    // Function to populate next pointers
    static void populateNext(Node root) {
        List<Node> nodes = new ArrayList<>();

        // Step 1: Store inorder traversal
        inorder(root, nodes);

        // Step 2: Link nodes
        for (int i = 0; i < nodes.size() - 1; i++) {
            nodes.get(i).next = nodes.get(i + 1);
        }

        // Step 3: Last node points to NULL
        if (!nodes.isEmpty())
            nodes.get(nodes.size() - 1).next = null;
    }

    public static void main(String[] args) {
        Node root = new Node(10);
        root.left = new Node(8);
        root.right = new Node(12);
        root.left.left = new Node(3);

        // Populate next pointers
        populateNext(root);
        
        // Print result
        List<Node> nodes = new ArrayList<>();
        inorder(root, nodes);
        for (int i = 0; i < nodes.size(); i++) {
            System.out.print(nodes.get(i).data + "->");
            if (nodes.get(i).next != null)
                System.out.print(nodes.get(i).next.data + " ");
            else
                System.out.print("-1 ");
        }
    }
}
Python
# Node Structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
        self.next = None


# Inorder traversal to store nodes
def inorder(root, nodes):
    if root is None:
        return
    inorder(root.left, nodes)
    nodes.append(root)
    inorder(root.right, nodes)


# Function to populate next pointers
def populateNext(root):
    nodes = []

    # Step 1: Store inorder traversal
    inorder(root, nodes)

    # Link nodes
    for i in range(len(nodes) - 1):
        nodes[i].next = nodes[i + 1]

    # Step 3: Last node points to NULL
    if nodes:
        nodes[-1].next = None


# Driver code
if __name__ == "__main__":
    root = Node(10)
    root.left = Node(8)
    root.right = Node(12)
    root.left.left = Node(3)

    # Populate next pointers
    populateNext(root)

    nodes = []
    inorder(root, nodes)

    for node in nodes:
        print(f"{node.data}->", end="")
        if node.next:
            print(node.next.data, end=" ")
        else:
            print("-1", end=" ")
    print()
C#
using System;
using System.Collections.Generic;

// Node structure
class Node
{
    public int data;
    public Node left, right, next;

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

class GfG
{
    // Inorder traversal to store nodes
    static void inorder(Node root, List<Node> nodes)
    {
        if (root == null)
            return;

        inorder(root.left, nodes);
        nodes.Add(root);
        inorder(root.right, nodes);
    }

    // Function to populate next pointers
    static void populateNext(Node root)
    {
        List<Node> nodes = new List<Node>();

        // Step 1: Store inorder traversal
        inorder(root, nodes);

        // Step 2: Link nodes
        for (int i = 0; i < nodes.Count - 1; i++)
        {
            nodes[i].next = nodes[i + 1];
        }

        // Step 3: Last node points to NULL
        if (nodes.Count > 0)
            nodes[nodes.Count - 1].next = null;
    }

    // Main function
    static void Main()
    {
        Node root = new Node(10);
        root.left = new Node(8);
        root.right = new Node(12);
        root.left.left = new Node(3);

        // Populate next pointers
        populateNext(root);
        
        // Print result
        List<Node> nodes = new List<Node>();
        inorder(root, nodes);
        for (int i = 0; i < nodes.Count; i++) {
            Console.Write(nodes[i].data + "->");
            if (nodes[i].next != null)
                Console.Write(nodes[i].next.data + " ");
            else
                Console.Write("-1 ");
        }
    }
}
JavaScript
// Node structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
        this.next = null;
    }
}

// Inorder traversal to store nodes
function inorder(root, nodes) {
    if (root === null) return;

    inorder(root.left, nodes);
    nodes.push(root);
    inorder(root.right, nodes);
}

// Function to populate next pointers
function populateNext(root) {
    let nodes = [];

    // Step 1: Store inorder traversal
    inorder(root, nodes);

    // Step 2: Link nodes
    for (let i = 0; i < nodes.length - 1; i++) {
        nodes[i].next = nodes[i + 1];
    }

    // Step 3: Last node points to null
    if (nodes.length > 0)
        nodes[nodes.length - 1].next = null;
}


// Driver code
let root = new Node(10);
root.left = new Node(8);
root.right = new Node(12);
root.left.left = new Node(3);

// Populate next pointers
populateNext(root);

// Print result
let nodes = [];
inorder(root, nodes);
let output = "";
for (let i = 0; i < nodes.length; i++) {
    output += nodes[i].data + "->";
    if (nodes[i].next)
        output += nodes[i].next.data + " ";
    else
        output += "-1 ";
}
console.log(output);

Output
3->8 8->10 10->12 12->-1

[Expected Approach] Reverse Inorder - O(n) Time and O(1) Space  

Traverse the given tree in reverse inorder traversal and keep track of previously visited node. When a node is being visited, assign a previously visited node as next.

C++
#include <iostream>
using namespace std;

// Node structure
struct Node
{
    int data;
    Node *left;
    Node *right;
    Node *next;

    Node(int val)
    {
        data = val;
        left = right = next = NULL;
    }
};

// Helper function (Reverse Inorder Traversal)
// Right → Root → Left
void populateNextUtil(Node *root, Node *&nextNode)
{
    if (root == NULL)
        return;

    // Step 1: Traverse right subtree first
    populateNextUtil(root->right, nextNode);

    // Step 2: Set next pointer
    root->next = nextNode;

    // Step 3: Update nextNode to current node
    nextNode = root;

    // Step 4: Traverse left subtree
    populateNextUtil(root->left, nextNode);
}

// Main function to populate next pointers
void populateNext(Node *root)
{
    Node *nextNode = NULL;
    populateNextUtil(root, nextNode);
}

// Driver code
int main()
{
    Node *root = new Node(10);

    root->left = new Node(8);
    root->right = new Node(12);
    root->left->left = new Node(3);

    // Populate next pointers
    populateNext(root);
    
    Node *curr = root;

    while (curr->left)
        curr = curr->left;

    while (curr != NULL)
    {
        cout << curr->data << "->";
        if (curr->next)
            cout << curr->next->data << " ";
        else
            cout << "-1 ";
        curr = curr->next;
    }

    cout << endl;

    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>

// Node structure
struct Node
{
    int data;
    struct Node* left;
    struct Node* right;
    struct Node* next;
};

// Function to create a new node
struct Node* newNode(int val)
{
    struct Node* node = (struct Node*)malloc(sizeof(struct Node));
    node->data = val;
    node->left = node->right = node->next = NULL;
    return node;
}

// Helper function (Reverse Inorder Traversal)
// Right → Root → Left
void populateNextUtil(struct Node* root, struct Node** nextNode)
{
    // Base case
    if (root == NULL)
        return;

    // Step 1: Traverse right subtree
    populateNextUtil(root->right, nextNode);

    // Step 2: Set next pointer
    root->next = *nextNode;

    // Step 3: Update nextNode to current node
    *nextNode = root;

    // Step 4: Traverse left subtree
    populateNextUtil(root->left, nextNode);
}

// Main function to populate next pointers
void populateNext(struct Node* root)
{
    
    // Initially NULL
    struct Node* nextNode = NULL; 
    populateNextUtil(root, &nextNode);
}

// Main function
int main()
{
    struct Node* root = newNode(10);
    root->left = newNode(8);
    root->right = newNode(12);
    root->left->left = newNode(3);

    // Populate next pointers
    populateNext(root);

    // Print result
    struct Node* curr = root;
    while (curr->left)
        curr = curr->left;

    // Traverse using next pointers
    while (curr != NULL) {
        printf("%d->", curr->data);
        if (curr->next)
            printf("%d ", curr->next->data);
        else
            printf("-1 ");
        curr = curr->next;
    }

    return 0;
}
Java
// Node structure
class Node {
    int data;
    Node left, right, next;

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

public class GfG {

    // Helper function (Reverse Inorder Traversal)
    static void populateNextUtil(Node root, Node[] nextNode) {

        // Base case
        if (root == null)
            return;

        // Step 1: Traverse right subtree
        populateNextUtil(root.right, nextNode);

        // Step 2: Set next pointer
        root.next = nextNode[0];

        // Step 3: Update nextNode
        nextNode[0] = root;

        // Step 4: Traverse left subtree
        populateNextUtil(root.left, nextNode);
    }

    // Main function to populate next pointers
    static void populateNext(Node root) {
        Node[] nextNode = new Node[1]; 
        nextNode[0] = null;
        populateNextUtil(root, nextNode);
    }

    // Main function
    public static void main(String[] args) {
        Node root = new Node(10);
        root.left = new Node(8);
        root.right = new Node(12);
        root.left.left = new Node(3);

        // Populate next pointers
        populateNext(root);
        
        // Print result
        Node curr = root;
        while (curr.left != null)
            curr = curr.left;

        // Traverse using next pointers
        while (curr != null) {
            System.out.print(curr.data + "->");
            if (curr.next != null)
                System.out.print(curr.next.data + " ");
            else
                System.out.print("-1 ");
            curr = curr.next;
        }
    }
}
Python
# Node structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
        self.next = None


# Helper function (Reverse Inorder Traversal)
def populateNextUtil(root, nextNode):
    
    # Base case
    if root is None:
        return

    # Step 1: Traverse right subtree
    populateNextUtil(root.right, nextNode)

    # Step 2: Set next pointer
    root.next = nextNode[0]

    # Step 3: Update nextNode
    nextNode[0] = root

    # Step 4: Traverse left subtree
    populateNextUtil(root.left, nextNode)


# Main function for populating next pointers
def populateNext(root):
    nextNode = [None]  
    
    # using list as reference
    populateNextUtil(root, nextNode)


# Driver Code
if __name__ == "__main__":
    root = Node(10)
    root.left = Node(8)
    root.right = Node(12)
    root.left.left = Node(3)

    populateNext(root)

    curr = root
    while curr.left:
        curr = curr.left

    while curr:
        print(f"{curr.data}->", end="")
        if curr.next:
            print(curr.next.data, end=" ")
        else:
            print("-1", end=" ")
        curr = curr.next
    print()
C#
using System;

// Node structure
class Node
{
    public int data;
    public Node left, right, next;

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

class GfG
{
    
    // Helper function (Reverse Inorder Traversal)
    // Right -> Root -> Left
    static void populateNextUtil(Node root, ref Node nextNode)
    {
        
        // Base case
        if (root == null)
            return;

        // Traverse right subtree
        populateNextUtil(root.right, ref nextNode);

        // Set next pointer
        root.next = nextNode;

        // Update nextNode
        nextNode = root;

        // Traverse left subtree
        populateNextUtil(root.left, ref nextNode);
    }

    // Main function for populating next pointers
    static void populateNext(Node root)
    {
        Node nextNode = null;
        populateNextUtil(root, ref nextNode);
    }

    // Print function
    static void printTree(Node root)
    {
        if (root == null)
            return;

        printTree(root.left);

        Console.Write(root.data + "->");
        if (root.next != null)
            Console.Write(root.next.data + " ");
        else
            Console.Write("-1");

        printTree(root.right);
    }

    // Main function
    static void Main()
    {
        Node root = new Node(10);
        root.left = new Node(8);
        root.right = new Node(12);
        root.left.left = new Node(3);

        // Populate next pointers
        populateNext(root);
        
        // Print result
        Node curr = root;
        while (curr.left != null)
            curr = curr.left;

        // Traverse using next pointers
        while (curr != null) {
            Console.Write(curr.data + "->");
            if (curr.next != null)
                Console.Write(curr.next.data + " ");
            else
                Console.Write("-1 ");
            curr = curr.next;
        }
    }
}
JavaScript
// Node structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
        this.next = null;
    }
}

// Helper function (Reverse Inorder Traversal)
function populateNextUtil(root, nextNode) {
    // Base case
    if (root === null) return;

    // Step 1: Traverse right subtree
    populateNextUtil(root.right, nextNode);

    // Step 2: Set next pointer
    root.next = nextNode.value;

    // Step 3: Update nextNode
    nextNode.value = root;

    // Step 4: Traverse left subtree
    populateNextUtil(root.left, nextNode);
}

// Main function for populating next pointers
function populateNext(root) {
    
    // object to mimic reference
    let nextNode = { value: null }; 
    populateNextUtil(root, nextNode);
}

// Driver code
let root = new Node(10);

root.left = new Node(8);
root.right = new Node(12);

root.left.left = new Node(3);

// Populating next pointers
populateNext(root);

// Print result
// Find leftmost node (inorder start)
let curr = root;
while (curr.left)
    curr = curr.left;

// Traverse using next pointers
let output = "";
while (curr !== null) {
    output += curr.data + "->";
    output += curr.next ? curr.next.data + " " : "-1 ";
    curr = curr.next;
}
console.log(output);

Output
3->8 8->10 10->12 12->-1
Comment