Height of a generic tree from parent array - GeeksforGeeks

24 Nov, 2021
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
Input  : parent[] = {-1, 0, 1, 2, 3}
Output : 4
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. 
C++
Java
Python3
C#
Javascript
// C++ code to find height of N-ary// tree in O(n)#include <bits/stdc++.h>#define MAX 1001using namespace std;  // Adjacency list to// store N-ary treevector<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 BFSint 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 Functionint 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 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 code to find height # of N-ary tree in O(n)from collections import deque  MAX = 1001  # Adjacency list to# store N-ary treeadj = [[] 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 BFSdef 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 codeif __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# 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
<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>
Height of N-ary Tree=4
 
The Time Complexity of this solution is O(2n) which converges to O(n) for very large 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:: 
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 visitedHence, we processed each node in the N-ary tree only once.  
C++
Java
Python3
C#
Javascript
// 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 lastint 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 Functionint 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 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 laststatic 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 Codepublic 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 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 Codeif __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# 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 laststatic 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 Codepublic 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
<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 lastfunction 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 Codelet 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>
Height of N-ary Tree = 2
 
Time Complexity: O(n)
PranchalKatiyar
29AjayKumar
Rajput-Ji
mohit kumar 29
rag2127
avanitrachhadiya2155
unknown2108
ab2127
rajutsav1234
n-ary-tree
Graph
Tree
Graph
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Disjoint Set (Or Union-Find) | Set 1 (Detect Cycle in an Undirected Graph)
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Traveling Salesman Problem (TSP) Implementation
Binary Tree | Set 1 (Introduction)
AVL Tree | Set 1 (Insertion)
Binary Tree | Set 3 (Types of Binary Tree)
Write a Program to Find the Maximum Depth or Height of a Tree
Binary Tree | Set 2 (Properties)