Open In App

Height of a generic tree from parent array

Last Updated : 22 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

We are given a tree of size n as array parent[0..n-1] where every index i in the parent[] represents a node and the value at i represents the immediate parent of that node. For root node value will be -1. Find the height of the generic tree given the parent links.

Examples: 

Input : parent[] = {-1, 0, 0, 0, 3, 1, 1, 2}
Output : 2

Height of a generic tree from parent array 1

Input  : parent[] = {-1, 0, 1, 2, 3}
Output : 4

Height of a generic tree from parent array 2

Here, a generic tree is sometimes also called an N-ary tree or N-way tree where N denotes the maximum number of child a node can have. In this problem, the array represents n number of nodes in the tree.

Approach 1: One solution is to traverse up the tree from the node till the root node is reached with node value -1. While Traversing for each node stores maximum path length. 
The Time Complexity of this solution is O(n^2).

Approach 2: Build graph for N-ary Tree in O(n) time and apply BFS on the stored graph in O(n) time and while doing BFS store maximum reached level. This solution does two iterations to find the height of N-ary tree.

Implementation:

C++




// C++ code to find height of N-ary
// tree in O(n)
#include <bits/stdc++.h>
#define MAX 1001
using namespace std;
 
// Adjacency list to
// store N-ary tree
vector<int> adj[MAX];
 
// Build tree in tree in O(n)
int build_tree(int arr[], int n)
{
    int root_index = 0;
 
    // Iterate for all nodes
    for (int i = 0; i < n; i++) {
 
        // if root node, store index
        if (arr[i] == -1)
            root_index = i;
 
        else {
            adj[i].push_back(arr[i]);
            adj[arr[i]].push_back(i);
        }
    }
    return root_index;
}
 
// Applying BFS
int BFS(int start)
{
    // map is used as visited array
    map<int, int> vis;
 
    queue<pair<int, int> > q;
    int max_level_reached = 0;
 
    // height of root node is zero
    q.push({ start, 0 });
 
    // p.first denotes node in adjacency list
    // p.second denotes level of p.first
    pair<int, int> p;
 
    while (!q.empty()) {
 
        p = q.front();
        vis[p.first] = 1;
 
        // store the maximum level reached
        max_level_reached = max(max_level_reached,
                                p.second);
 
        q.pop();
 
        for (int i = 0; i < adj[p.first].size(); i++)
 
            // adding 1 to previous level
            // stored on node p.first
            // which is parent of node adj[p.first][i]
            // if adj[p.first][i] is not visited
            if (!vis[adj[p.first][i]])
                q.push({ adj[p.first][i], p.second + 1 });
    }
 
    return max_level_reached;
}
 
// Driver Function
int main()
{
    // node 0 to node n-1
    int parent[] = { -1, 0, 1, 2, 3 };
 
    // Number of nodes in tree
    int n = sizeof(parent) / sizeof(parent[0]);
 
    int root_index = build_tree(parent, n);
 
    int ma = BFS(root_index);
    cout << "Height of N-ary Tree=" << ma;
    return 0;
}


Java




// Java code to find height of N-ary
// tree in O(n)
import java.io.*;
import java.util.*;
 
class GFG
{
    static int MAX = 1001;
   
    // Adjacency list to
    // store N-ary tree
    static ArrayList<ArrayList<Integer>> adj =
      new ArrayList<ArrayList<Integer>>();
     
    // Build tree in tree in O(n)
    static int build_tree(int arr[], int n)
    {
        int root_index = 0;
  
        // Iterate for all nodes
        for (int i = 0; i < n; i++)
        {
  
            // if root node, store index
            if (arr[i] == -1)
                root_index = i;
  
            else
            {
                adj.get(i).add(arr[i]);
                adj.get(arr[i]).add(i);
            }
        }
        return root_index;
    }
     
    // Applying BFS
    static int BFS(int start)
    {
       
        // map is used as visited array
        Map<Integer, Integer> vis = new HashMap<Integer, Integer>();
        ArrayList<ArrayList<Integer>> q = new ArrayList<ArrayList<Integer>>();
        int max_level_reached = 0;
  
        // height of root node is zero
        q.add(new ArrayList<Integer>(Arrays.asList(start, 0 )));
       
        // p.first denotes node in adjacency list
        // p.second denotes level of p.first
        ArrayList<Integer> p = new ArrayList<Integer>();
        while(q.size() != 0)
        {
            p = q.get(0);
            vis.put(p.get(0),1);
           
            // store the maximum level reached
            max_level_reached = Math.max(max_level_reached,p.get(1));
            q.remove(0);
            for(int i = 0; i < adj.get(p.get(0)).size(); i++)
            {
               
                // adding 1 to previous level
                // stored on node p.first
                // which is parent of node adj[p.first][i]
                // if adj[p.first][i] is not visited
                if(!vis.containsKey(adj.get(p.get(0)).get(i)))
                {
                    q.add(new ArrayList<Integer>(Arrays.asList(adj.get(p.get(0)).get(i), p.get(1)+1)));
                }
            }
        }
        return max_level_reached;
    }
   
    // Driver Function
    public static void main (String[] args)
    {
        for(int i = 0; i < MAX; i++)
        {
            adj.add(new ArrayList<Integer>());
        }
         
        // node 0 to node n-1
        int parent[] = { -1, 0, 1, 2, 3 };
         
        // Number of nodes in tree
        int n = parent.length;
        int root_index = build_tree(parent, n);
        int ma = BFS(root_index);
        System.out.println( "Height of N-ary Tree=" + ma);
    }
}
 
// This code is contributed by rag2127


Python3




# Python3 code to find height
# of N-ary tree in O(n)
from collections import deque
 
MAX = 1001
 
# Adjacency list to
# store N-ary tree
adj = [[] for i in range(MAX)]
 
# Build tree in tree in O(n)
def build_tree(arr, n):
   
    root_index = 0
 
    # Iterate for all nodes
    for i in range(n):
 
        # if root node, store
        # index
        if (arr[i] == -1):
            root_index = i
        else:
            adj[i].append(arr[i])
            adj[arr[i]].append(i)
 
    return root_index
 
# Applying BFS
def BFS(start):
   
    # map is used as visited
    # array
    vis = {}
 
    q = deque()
    max_level_reached = 0
 
    # height of root node is
    # zero
    q.append([start, 0])
 
    # p.first denotes node in
    # adjacency list
    # p.second denotes level of
    # p.first
    p = []
 
    while (len(q) > 0):
        p = q.popleft()
        vis[p[0]] = 1
 
        # store the maximum level
        # reached
        max_level_reached = max(max_level_reached,
                                p[1])
 
        for i in range(len(adj[p[0]])):
 
            # adding 1 to previous level
            # stored on node p.first
            # which is parent of node
            # adj[p.first][i]
            # if adj[p.first][i] is not visited
            if (adj[p[0]][i] not in vis ):
                q.append([adj[p[0]][i],
                          p[1] + 1])
 
    return max_level_reached
 
# Driver code
if __name__ == '__main__':
   
    # node 0 to node n-1
    parent = [-1, 0, 1, 2, 3]
 
    # Number of nodes in tree
    n = len(parent)
 
    root_index = build_tree(parent, n)
    ma = BFS(root_index)
    print("Height of N-ary Tree=",
          ma)
 
# This code is contributed by Mohit Kumar 29


C#




// C# code to find height of N-ary
// tree in O(n)
using System;
using System.Collections.Generic;
 
public class GFG
{
  static int MAX = 1001;
 
  // Adjacency list to
  // store N-ary tree
  static List<List<int>> adj = new List<List<int>>();
 
  // Build tree in tree in O(n)
  static int build_tree(int[] arr, int n)
  {
    int root_index = 0;
 
    // Iterate for all nodes
    for (int i = 0; i < n; i++)
    {
 
      // if root node, store index
      if (arr[i] == -1)
        root_index = i;
      else
      {
        adj[i].Add(arr[i]);
        adj[arr[i]].Add(i);
      }
    }
    return root_index;   
  }
 
  // Applying BFS
  static int BFS(int start)
  {
    // map is used as visited array
    Dictionary<int, int> vis = new Dictionary<int, int>(); 
    List<List<int>> q= new List<List<int>>();
    int max_level_reached = 0;
 
    // height of root node is zero
    q.Add(new List<int>(){start, 0});
 
    // p.first denotes node in adjacency list
    // p.second denotes level of p.first
    List<int> p = new List<int>();
 
    while(q.Count != 0)
    {
      p = q[0];
      vis.Add(p[0], 1);
 
      // store the maximum level reached
      max_level_reached = Math.Max(max_level_reached, p[1]);
      q.RemoveAt(0);
      for(int i = 0; i < adj[p[0]].Count; i++)
      {
        // adding 1 to previous level
        // stored on node p.first
        // which is parent of node adj[p.first][i]
        // if adj[p.first][i] is not visited
        if(!vis.ContainsKey(adj[p[0]][i]))
        {
          q.Add(new List<int>(){adj[p[0]][i], p[1] + 1 });
        }
      }
    }
    return max_level_reached;
  }
 
  // Driver Function
  static public void Main ()
  {
    for(int i = 0; i < MAX; i++)
    {
      adj.Add(new List<int>());
    }
 
    // node 0 to node n-1
    int[] parent = { -1, 0, 1, 2, 3 };
     
    // Number of nodes in tree
    int n = parent.Length;
    int root_index = build_tree(parent, n);
    int ma = BFS(root_index);
    Console.Write("Height of N-ary Tree=" + ma);
  }
}
 
// This code is contributed by avanitrachhadiya2155


Javascript




<script>
 
// JavaScript code to find height of N-ary
// tree in O(n)
 
    let MAX = 1001;
    let adj = [];
     
    // Adjacency list to
    // store N-ary tree
    function build_tree(arr,n)
    {
        let root_index = 0;
   
        // Iterate for all nodes
        for (let i = 0; i < n; i++)
        {
   
            // if root node, store index
            if (arr[i] == -1)
                root_index = i;
   
            else
            {
                adj[i].push(arr[i]);
                adj[arr[i]].push(i);
            }
        }
        return root_index;
    }
     
    // Applying BFS
    function BFS(start)
    {
        // map is used as visited array
        let vis = new Map();
        let q = [];
        let max_level_reached = 0;
   
        // height of root node is zero
        q.push([start, 0 ]);
        
        // p.first denotes node in adjacency list
        // p.second denotes level of p.first
        let p = [];
        while(q.length != 0)
        {
            p = q[0];
            vis.set(p[0],1);
            
            // store the maximum level reached
            max_level_reached =
            Math.max(max_level_reached,p[1]);
            q.shift();
            for(let i = 0; i < adj[p[0]].length; i++)
            {
                
                // adding 1 to previous level
                // stored on node p.first
                // which is parent of node adj[p.first][i]
                // if adj[p.first][i] is not visited
                if(!vis.has(adj[p[0]][i]))
                {
                    q.push([adj[p[0]][i], p[1]+1]);
                }
            }
        }
        return max_level_reached;
    }
     
     // Driver Function
    for(let i = 0; i < MAX; i++)
        {
            adj.push([]);
        }
          
        // node 0 to node n-1
        let parent = [ -1, 0, 1, 2, 3 ];
          
        // Number of nodes in tree
        let n = parent.length;
        let root_index = build_tree(parent, n);
        let ma = BFS(root_index);
        document.write( "Height of N-ary Tree=" + ma);
       
 
 
// This code is contributed by unknown2108
 
</script>


Output: 

Height of N-ary Tree=4

 

Time Complexity: O(n) which converges to O(n) for very large n.
Auxiliary Space: O(n), we are using an adjacency list to store the tree in memory. The size of the adjacency list is proportional to the number of nodes in the tree, so the space complexity of the algorithm is O(n).

Approach 3: 

We can find the height of the N-ary Tree in only one iteration. We visit nodes from 0 to n-1 iteratively and mark the unvisited ancestors recursively if they are not visited before till we reach a node which is visited, or we reach the root node. If we reach the visited node while traversing up the tree using parent links, then we use its height and will not go further in recursion.

Explanation For Example 1:

Height of a generic tree from parent array 3

  • For node 0: Check for Root node is true, 
    Return 0 as height, Mark node 0 as visited 
  • For node 1: Recur for an immediate ancestor, i.e 0, which is already visited 
    So, Use its height and return height(node 0) +1 
    Mark node 1 as visited 
  • For node 2: Recur for an immediate ancestor, i.e 0, which is already visited 
    So, Use its height and return height(node 0) +1 
    Mark node 2 as visited 
  • For node 3: Recur for an immediate ancestor, i.e 0, which is already visited 
    So, Use its height and return height(node 0) +1 
    Mark node 3 as visited 
  • For node 4: Recur for an immediate ancestor, i.e 3, which is already visited 
    So, Use its height and return height(node 3) +1 
    Mark node 3 as visited 
  • For node 5: Recur for an immediate ancestor, i.e 1, which is already visited 
    So, Use its height and return height(node 1) +1 
    Mark node 5 as visited 
  • For node 6: Recur for an immediate ancestor, i.e 1, which is already visited 
    So, Use its height and return height(node 1) +1 
    Mark node 6 as visited 
  • For node 7: Recur for an immediate ancestor, i.e 2, which is already visited 
    So, Use its height and return height(node 2) +1 
  • Mark node 7 as visited
    Hence, we processed each node in the N-ary tree only once. 

Implementation:

C++




// C++ code to find height of N-ary
// tree in O(n) (Efficient Approach)
#include <bits/stdc++.h>
using namespace std;
 
// Recur For Ancestors of node and
// store height of node at last
int fillHeight(int p[], int node, int visited[],
                                   int height[])
{
    // If root node
    if (p[node] == -1) {
 
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
 
    // If node is already visited
    if (visited[node])
        return height[node];
 
    // Visit node and calculate its height
    visited[node] = 1;
 
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
 
    // return calculated height for node
    return height[node];
}
 
int findHeight(int parent[], int n)
{
    // To store max height
    int ma = 0;
 
    // To check whether or not node is visited before
    int visited[n];
 
    // For Storing Height of node
    int height[n];
 
    memset(visited, 0, sizeof(visited));
    memset(height, 0, sizeof(height));
 
    for (int i = 0; i < n; i++) {
 
        // If not visited before
        if (!visited[i])
            height[i] = fillHeight(parent, i,
                             visited, height);
 
        // store maximum height so far
        ma = max(ma, height[i]);
    }
 
    return ma;
}
 
// Driver Function
int main()
{
    int parent[] = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = sizeof(parent) / sizeof(parent[0]);
 
    cout << "Height of N-ary Tree = "
         << findHeight(parent, n);
    return 0;
}


Java




// Java code to find height of N-ary
// tree in O(n) (Efficient Approach)
import java.util.*;
class GFG
{
 
// Recur For Ancestors of node and
// store height of node at last
static int fillHeight(int p[], int node,
                      int visited[], int height[])
{
    // If root node
    if (p[node] == -1)
    {
 
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
 
    // If node is already visited
    if (visited[node] == 1)
        return height[node];
 
    // Visit node and calculate its height
    visited[node] = 1;
 
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
 
    // return calculated height for node
    return height[node];
}
 
static int findHeight(int parent[], int n)
{
    // To store max height
    int ma = 0;
 
    // To check whether or not node is visited before
    int []visited = new int[n];
 
    // For Storing Height of node
    int []height = new int[n];
 
    for(int i = 0; i < n; i++)
    {
        visited[i] = 0;
        height[i] = 0;
    }
 
    for (int i = 0; i < n; i++)
    {
 
        // If not visited before
        if (visited[i] != 1)
         
            height[i] = fillHeight(parent, i,
                            visited, height);
 
        // store maximum height so far
        ma = Math.max(ma, height[i]);
    }
    return ma;
}
 
// Driver Code
public static void main(String[] args)
{
    int parent[] = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = parent.length;
 
    System.out.println("Height of N-ary Tree = " +
                           findHeight(parent, n));
}
}
 
// This code is contributed by 29AjayKumar


Python3




# Python3 code to find height of N-ary
# tree in O(n) (Efficient Approach)
 
# Recur For Ancestors of node and
# store height of node at last
def fillHeight(p, node, visited, height):
     
    # If root node
    if (p[node] == -1):
 
        # mark root node as visited
        visited[node] = 1
        return 0
 
    # If node is already visited
    if (visited[node]):
        return height[node]
 
    # Visit node and calculate its height
    visited[node] = 1
 
    # recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                                  visited, height)
 
    # return calculated height for node
    return height[node]
 
def findHeight(parent, n):
     
    # To store max height
    ma = 0
 
    # To check whether or not node is
    # visited before
    visited = [0] * n
 
    # For Storing Height of node
    height = [0] * n
 
    for i in range(n):
 
        # If not visited before
        if (not visited[i]):
            height[i] = fillHeight(parent, i,
                                   visited, height)
 
        # store maximum height so far
        ma = max(ma, height[i])
 
    return ma
 
# Driver Code
if __name__ == '__main__':
 
    parent = [-1, 0, 0, 0, 3, 1, 1, 2]
    n = len(parent)
 
    print("Height of N-ary Tree =",
             findHeight(parent, n))
 
# This code is contributed by PranchalK


C#




// C# code to find height of N-ary
// tree in O(n) (Efficient Approach)
using System;
     
class GFG
{
 
// Recur For Ancestors of node and
// store height of node at last
static int fillHeight(int []p, int node,
                      int []visited,
                      int []height)
{
    // If root node
    if (p[node] == -1)
    {
 
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
 
    // If node is already visited
    if (visited[node] == 1)
        return height[node];
 
    // Visit node and calculate its height
    visited[node] = 1;
 
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
 
    // return calculated height for node
    return height[node];
}
 
static int findHeight(int []parent, int n)
{
    // To store max height
    int ma = 0;
 
    // To check whether or not
    // node is visited before
    int []visited = new int[n];
 
    // For Storing Height of node
    int []height = new int[n];
 
    for(int i = 0; i < n; i++)
    {
        visited[i] = 0;
        height[i] = 0;
    }
 
    for (int i = 0; i < n; i++)
    {
 
        // If not visited before
        if (visited[i] != 1)
         
            height[i] = fillHeight(parent, i,
                            visited, height);
 
        // store maximum height so far
        ma = Math.Max(ma, height[i]);
    }
    return ma;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []parent = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = parent.Length;
 
    Console.WriteLine("Height of N-ary Tree = " +
                          findHeight(parent, n));
}
}
 
// This code contributed by Rajput-Ji


Javascript




<script>
// Javascript code to find height of N-ary
// tree in O(n) (Efficient Approach)
 
// Recur For Ancestors of node and
// store height of node at last
function fillHeight(p, node, visited, height)
{
 
    // If root node
    if (p[node] == -1)
    {
  
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
  
    // If node is already visited
    if (visited[node] == 1)
        return height[node];
  
    // Visit node and calculate its height
    visited[node] = 1;
  
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
  
    // return calculated height for node
    return height[node];
}
 
function findHeight(parent,n)
{
    // To store max height
    let ma = 0;
  
    // To check whether or not node is visited before
    let visited = new Array(n);
  
    // For Storing Height of node
    let height = new Array(n);
  
    for(let i = 0; i < n; i++)
    {
        visited[i] = 0;
        height[i] = 0;
    }
  
    for (let i = 0; i < n; i++)
    {
  
        // If not visited before
        if (visited[i] != 1)
          
            height[i] = fillHeight(parent, i,
                            visited, height);
  
        // store maximum height so far
        ma = Math.max(ma, height[i]);
    }
    return ma;
}
 
// Driver Code
let parent = [ -1, 0, 0, 0, 3, 1, 1, 2 ];
let  n = parent.length;
document.write("Height of N-ary Tree = " +
                           findHeight(parent, n));
 
// This code is contributed by ab2127
</script>


Output: 

Height of N-ary Tree = 2

 

Time Complexity: O(n)
Auxiliary Space: O(n), this is because we need to store the visited and height arrays which are of size n.



Previous Article
Next Article

Similar Reads

Convert a Generic Tree(N-array Tree) to Binary Tree
Prerequisite: Generic Trees(N-array Trees) In this article, we will discuss the conversion of the Generic Tree to a Binary Tree. Following are the rules to convert a Generic(N-array Tree) to a Binary Tree: The root of the Binary Tree is the Root of the Generic Tree.The left child of a node in the Generic Tree is the Left child of that node in the B
13 min read
Find Height of Binary Tree represented by Parent array
A given array represents a tree in such a way that the array value gives the parent node of that particular index. The value of the root node index would always be -1. Find the height of the tree. The height of a Binary Tree is the number of nodes on the path from the root to the deepest leaf node, and the number includes both root and leaf. Input:
13 min read
Height of n-ary tree if parent array is given
Given a parent array P, where P[i] indicates the parent of the ith node in the tree(assume parent of root node id indicated with -1). Find the height of the tree. Examples: Input : array[] = [-1 0 1 6 6 0 0 2 7]Output : height = 5Tree formed is: 0 / | \ 5 1 6 / | \ 2 4 3 / 7 / 8 Start at each node and keep going to its parent until we reach -1. Als
10 min read
Remove all leaf nodes from a Generic Tree or N-ary Tree
Given a Generic tree, the task is to delete the leaf nodes from the tree. Examples: Input: 5 / / \ \ 1 2 3 8 / / \ \ 15 4 5 6 Output: 5 : 1 2 3 1 : 2 : 3 : Explanation: Deleted leafs are: 8, 15, 4, 5, 6 Input: 8 / | \ 9 7 2 / | \ | / / | \ \ 4 5 6 10 11 1 2 2 3 Output: 8: 9 7 2 9: 7: 2: Approach: Follow the steps given below to solve the problem Co
9 min read
Check if given Generic N-ary Tree is Symmetric horizontally
Given an N-ary tree root, the task is to check if it is symmetric horizontally (Mirror image of itself). Example: Input: root = 7 / / \ \ 4 2 2 4 / | / | | \ | \ 3 2 6 7 7 6 2 3Output: trueExplanation: The left side of the tree is a mirror image of the right side Input: root= 2 / | \ 3 4 3 / | \ 5 6 5Output: true Approach: The given problem can be
8 min read
Left and Right view of a Generic Tree
Given a Generic Tree consisting of N nodes, the task is to find the left and right views of the given generic Tree. Examples: Input: 1 / \ 2 3 / \ / \ \4 5 6 7 8 Output:Left View: 1 2 4 Right View: 1 3 8 Explanation:When the tree is viewed from the left side, then the nodes which are visible is 1 2 4.When the tree is viewed from the right side, the
9 min read
Generic Tree meaning & definition in DSA
A generic tree (or N-ary Tree) is a type of tree data structure where each node can have at most N number of children where N can be any integer. Characteristics of Generic Tree:Each node can have zero or more child nodes.A node can have N number of children where N can be any integer.Each node has a list of pointers that point to the children.Appl
2 min read
Replace every node with depth in N-ary Generic Tree
Given an array arr[] representing a Generic(N-ary) tree. The task is to replace the node data with the depth(level) of the node. Assume level of root to be 0. Array Representation: The N-ary tree is serialized in the array arr[] using level order traversal as described below:   The input is given as a level order traversal of N-ary Tree.The first e
15+ min read
Maximum height of an elevation possible such that adjacent matrix cells have a difference of at most height 1
Given a matrix mat][][] of size M x N which represents the topographic map of a region, and 0 denotes land and 1 denotes elevation, the task is to maximize the height in the matrix by assigning each cell a non-negative height such that the height of a land cell is 0 and two adjacent cells must have an absolute height difference of at most 1. Exampl
12 min read
Construct Binary Tree from given Parent Array representation | Iterative Approach
Given an array that represents a tree in such a way that array indexes are values in tree nodes and array values give the parent node of that particular index (or node). The value of the root node index would always be -1 as there is no parent for root. Construct the standard linked representation of given Binary Tree from this given representation
12 min read
Article Tags :
Practice Tags :