Open In App

Find root of n-ary tree from given list of nodes

Last Updated : 16 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an N-ary tree as a list of nodes Node[] tree. Each node has a unique value, the task is to find the root of the tree.

N-ary tree

Examples:

Input:          1                   
                /   |   \              
              2   3   4           
              \                    
              5

Output: Root value is 1
 

Input:                5      
                     /     |    \
                   3      6   7
                  /  \    /  \
                 9 2   1 8

Output: Root value is 5

Naive approach: To solve the problem follow the below idea:

The basic way to find the root of an N-ary tree, we can iterate over each node and will check if it appears as a child node in any other node this way if we find a node that doesn’t appear as a child in any other node can be said or considered as the root of the tree.

Time Complexity: O(N*N), where N is the number of nodes 
Auxiliary Space: O(N) where N is the number of nodes

Efficient approach: To solve the problem follow the below idea:

In order to find the root of an N-ary tree we can utilize the properties of a tree structure, as we know in a generic tree the root node does not appear as a child so we will iterate over each node and keep track of their parents and the node without a parent is the root of the tree.

Illustrations:

Let’s consider the below example to understand the above approach easily

Tree :          1                   
                /   |   \              
              2   3   4           
               |                    
               5

Steps of illustrations:

  • Begin with an empty dictionary to hold each node’s parents.
  • Iterate through the tree nodes.
  • Iterate over the children of each node
  • For each child node, add an item to the parent dictionary with the key being the child node and the value being the parent node.
  • We will have a dictionary that maps each child’s node to its parent node after iterating over all nodes and their children.
  • Iterate through the tree, looking for nodes that have children in other nodes.
  • If a node does not appear as a child in any other node, it is called the tree’s root.
  • In the given example, the node 1 doesn’t appear as a child in any other node so it can be said that node 1 is the root node.

Below is the implementation of the above approach in Python:

C++




#include <iostream>
#include <vector>
#include <unordered_map>
 
class Node {
public:
    int value;
    std::vector<Node*> children;
 
    Node(int value) : value(value) {}
};
 
Node* findRoot(std::vector<Node*>& tree) {
    std::unordered_map<Node*, Node*> parents;
 
    // Iterate over each node and its children
    for (Node* node : tree) {
        for (Node* child : node->children) {
            parents[child] = node;
        }
    }
 
    // Find the root node by checking for a node without a parent
    for (Node* node : tree) {
        if (parents.find(node) == parents.end()) {
            return node;
        }
    }
 
    // No root found
    return nullptr;
}
 
int main() {
    // Create the nodes for the given example tree
    Node* node1 = new Node(5);
    Node* node2 = new Node(3);
    Node* node3 = new Node(6);
    Node* node4 = new Node(7);
    Node* node5 = new Node(9);
    Node* node6 = new Node(2);
    Node* node7 = new Node(1);
    Node* node8 = new Node(8);
 
    // Define the relationships between the nodes
    node1->children = { node2, node3, node4 };
    node2->children = { node5, node6 };
    node4->children = { node7, node8 };
 
    // Create the vector of nodes representing the tree
    std::vector<Node*> tree = { node1, node2, node3, node4, node5,
                                node6, node7, node8 };
 
    // Find the root of the tree
    Node* root = findRoot(tree);
 
    // Print the value of the root node
    if (root) {
        std::cout << "Root value: " << root->value << std::endl;
    } else {
        std::cout << "No root found." << std::endl;
    }
 
    // Clean up the dynamically allocated nodes
    for (Node* node : tree) {
        delete node;
    }
 
    return 0;
}


Java




// Java program of the above approach
import java.util.*;
 
class Node {
    int value;
    List<Node> children;
 
    Node(int value)
    {
        this.value = value;
        this.children = new ArrayList<>();
    }
}
 
public class GFG {
    static Node findRoot(List<Node> tree)
    {
        Map<Node, Node> parents = new HashMap<>();
 
        // Iterate over each node and its children
        for (Node node : tree) {
            for (Node child : node.children) {
                parents.put(child, node);
            }
        }
 
        // Find the root node by checking for a node without
        // a parent
        for (Node node : tree) {
            if (!parents.containsKey(node)) {
                return node;
            }
        }
 
        // No root found
        return null;
    }
 
    public static void main(String[] args)
    {
        // Create the nodes for the given example tree
        Node node1 = new Node(5);
        Node node2 = new Node(3);
        Node node3 = new Node(6);
        Node node4 = new Node(7);
        Node node5 = new Node(9);
        Node node6 = new Node(2);
        Node node7 = new Node(1);
        Node node8 = new Node(8);
 
        // Define the relationships between the nodes
        node1.children.add(node2);
        node1.children.add(node3);
        node1.children.add(node4);
        node2.children.add(node5);
        node2.children.add(node6);
        node4.children.add(node7);
        node4.children.add(node8);
 
        // Create the list of nodes representing the tree
        List<Node> tree = new ArrayList<>();
        tree.add(node1);
        tree.add(node2);
        tree.add(node3);
        tree.add(node4);
        tree.add(node5);
        tree.add(node6);
        tree.add(node7);
        tree.add(node8);
 
        // Find the root of the tree
        Node root = findRoot(tree);
 
        // Print the value of the root node
        if (root != null) {
            System.out.println("Root value: " + root.value);
        }
        else {
            System.out.println("No root found.");
        }
    }
}
 
// This code is contributed by Susobhan Akhuli


Python3




class Node:
    def __init__(self, value):
        self.value = value
        self.children = []
 
 
def find_root(tree):
    parents = {}
 
    # Iterate over each node
    # and its children
    for node in tree:
        for child in node.children:
            parents[child] = node
 
    # Find the root node by checking
    # for a node without a parent
    for node in tree:
        if node not in parents:
            return node
 
# No root found
    return None
 
 
# Create the nodes for the
# given example tree
node1 = Node(5)
node2 = Node(3)
node3 = Node(6)
node4 = Node(7)
node5 = Node(9)
node6 = Node(2)
node7 = Node(1)
node8 = Node(8)
 
# Define the relationships
# between the nodes
node1.children = [node2, node3, node4]
node2.children = [node5, node6]
node4.children = [node7, node8]
 
# Create the list of nodes
# representing the tree
tree = [node1, node2, node3,
        node4, node5, node6, node7, node8]
 
# Find the root of the tree
root = find_root(tree)
 
# Print the value of
# the root node
if root:
    print("Root value:", root.value)
else:
    print("No root found.")


C#




// C# program of the above approach
using System;
using System.Collections.Generic;
 
public class Node {
    public int Value;
    public List<Node> Children;
 
    public Node(int value)
    {
        Value = value;
        Children = new List<Node>();
    }
}
 
public class GFG {
    static Node FindRoot(List<Node> tree)
    {
        Dictionary<Node, Node> parents
            = new Dictionary<Node, Node>();
 
        // Iterate over each node and its children
        foreach(Node node in tree)
        {
            foreach(Node child in node.Children)
            {
                parents[child] = node;
            }
        }
 
        // Find the root node by checking for a node without
        // a parent
        foreach(Node node in tree)
        {
            if (!parents.ContainsKey(node)) {
                return node;
            }
        }
 
        // No root found
        return null;
    }
 
    public static void Main(string[] args)
    {
        // Create the nodes for the given example tree
        Node node1 = new Node(5);
        Node node2 = new Node(3);
        Node node3 = new Node(6);
        Node node4 = new Node(7);
        Node node5 = new Node(9);
        Node node6 = new Node(2);
        Node node7 = new Node(1);
        Node node8 = new Node(8);
 
        // Define the relationships between the nodes
        node1.Children.AddRange(
            new[] { node2, node3, node4 });
        node2.Children.AddRange(new[] { node5, node6 });
        node4.Children.AddRange(new[] { node7, node8 });
 
        // Create the list of nodes representing the tree
        List<Node> tree
            = new List<Node>{ node1, node2, node3, node4,
                              node5, node6, node7, node8 };
 
        // Find the root of the tree
        Node root = FindRoot(tree);
 
        // Print the value of the root node
        if (root != null) {
            Console.WriteLine($"Root value: { root.Value }");
        }
        else {
            Console.WriteLine("No root found.");
        }
 
        // Clean up the dynamically allocated nodes
        foreach(Node node in tree)
        {
            // Since C# uses automatic memory management
            // (garbage collection), manual memory
            // deallocation (delete) is not necessary. The
            // nodes will be automatically cleaned up when
            // they are no longer referenced.
        }
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




<script>
// Javascript program of the above approach
 
class Node {
    constructor(value) {
        this.value = value;
        this.children = [];
    }
}
 
function findRoot(tree) {
    const parents = new Map();
 
    // Iterate over each node and its children
    for (const node of tree) {
        for (const child of node.children) {
            parents.set(child, node);
        }
    }
 
    // Find the root node by checking for a node without a parent
    for (const node of tree) {
        if (!parents.has(node)) {
            return node;
        }
    }
 
    // No root found
    return null;
}
 
// Create the nodes for the given example tree
const node1 = new Node(5);
const node2 = new Node(3);
const node3 = new Node(6);
const node4 = new Node(7);
const node5 = new Node(9);
const node6 = new Node(2);
const node7 = new Node(1);
const node8 = new Node(8);
 
// Define the relationships between the nodes
node1.children = [node2, node3, node4];
node2.children = [node5, node6];
node4.children = [node7, node8];
 
// Create the array of nodes representing the tree
const tree = [node1, node2, node3, node4, node5, node6, node7, node8];
 
// Find the root of the tree
const root = findRoot(tree);
 
// Print the value of the root node
if (root) {
  document.write("Root value:", root.value);
}
 
else {
  document.write("No root found.");
}
 
// Clean up the dynamically allocated nodes
for (const node of tree) {
  delete node;
}
 
// This code is contributed by Susobhan Akhuli
</script>


Output

Root value: 5

Time Complexity: O(N), where N is the number of nodes 
Auxiliary Space: O(N) where N is the number of nodes



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads