Count ancestors with smaller value for each node of a Binary Tree - GeeksforGeeks

01 Jun, 2021
Given a Binary Tree consisting of N nodes, valued from 1 to N, rooted at node 1, the task is for each node is to count the number of ancestors with a value smaller than that of the current node.
Examples:
Input: Below is the given Tree:                    1                   / \                 4   5               /     /\             6    3  2Output: 0 1 1 1 1 2Explanation: Since node 1 is the root node, it has no ancestors.Ancestors of node 2: {1, 5}. Number of ancestors having value smaller than 2 is 1.Ancestors of node 3: {1, 5}. Number of ancestors having value smaller than 3 is 1.Ancestors of node 4: {1}. Number of ancestors having value smaller than 4 is 1.Ancestors of node 5: {1}. Number of ancestors having value smaller than 5 is 1.Ancestors of node 6: {1, 4}. Number of ancestors having value smaller than 6 is 2.
Input: Below is the given Tree:                  1                / \              3   2                    \                     4Output: 0 1 1 2   Explanation: Node 1 has no ancestors.Ancestors of node 2: {1}. Number of ancestors having value smaller than 2 is 1.Ancestors of node 3: {1}. Number of ancestors having value smaller than 3 is 1.Ancestors of node 4: {1, 2}. Number of ancestors having value smaller than 4 is 2.
Approach: The idea is to perform DFS traversal from the root node of the Tree and store the immediate parent of each node in an array. Then iterate over each node and using the parent array, compare its value with all its ancestors. Finally, print the result. Follow the steps below to solve the problem:
Initialize an array, say par[] of size N, with -1, to store the immediate parent of each node.
Perform DFS traversal from the root node and perform the following steps:Update the parent of the current node.Recursively call the children of the current node.
Update the parent of the current node.
Recursively call the children of the current node.
Now, iterate over the range [1, N] using a variable i and perform the following steps:Store the current node in a variable, say node.Iterate while par[node] is not equal to -1:If par[node] is less than i, then increment cnt by 1.Update node as par[node].After completing the above steps, print the value of cnt as the value for the current node.
Store the current node in a variable, say node.
Iterate while par[node] is not equal to -1:If par[node] is less than i, then increment cnt by 1.Update node as par[node].
If par[node] is less than i, then increment cnt by 1.
Update node as par[node].
After completing the above steps, print the value of cnt as the value for the current node.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to add an edge// between nodes u and vvoid add_edge(vector<int> adj[],              int u, int v){    adj[u].push_back(v);    adj[v].push_back(u);} // Function to perform the DFS Traversal// and store parent of each nodevoid dfs(vector<int>& parent,         vector<int> adj[],         int u,         int par = -1){    // Store the immediate parent    parent[u] = par;     // Traverse the children of    // the current node    for (auto child : adj[u]) {         // Recursively call for        // function dfs for the        // child node        if (child != par)            dfs(parent, adj, child, u);    }} // Function to count the number of// ancestors with values smaller// than that of the current nodevoid countSmallerAncestors(    vector<int> adj[], int n){    // Stores the parent of each node    vector<int> parent(int(1e5), 0);     // Perform the DFS Traversal    dfs(parent, adj, 1);     // Traverse all the nodes    for (int i = 1; i <= n; i++) {         int node = i;         // Store the number of ancestors        // smaller than node        int cnt = 0;         // Loop until parent[node] != -1        while (parent[node] != -1) {             // If the condition satisfies,            // increment cnt by 1            if (parent[node] < i)                cnt += 1;             node = parent[node];        }         // Print the required result        // for the current node        cout << cnt << " ";    }} // Driver Codeint main(){    int N = 6;    vector<int> adj[int(1e5)];     // Tree Formation    add_edge(adj, 1, 5);    add_edge(adj, 1, 4);    add_edge(adj, 4, 6);    add_edge(adj, 5, 3);    add_edge(adj, 5, 2);     countSmallerAncestors(adj, N);     return 0;}
// Java program for the above approachimport java.io.*;import java.util.*; class GFG{     // Function to add an edge// between nodes u and vstatic void add_edge(ArrayList<ArrayList<Integer>> adj,                     int u, int v){    adj.get(u).add(v);    adj.get(v).add(u);}   // Function to perform the DFS Traversal// and store parent of each nodestatic void dfs(ArrayList<Integer> parent,                ArrayList<ArrayList<Integer>> adj,                int u, int par){         // Store the immediate parent    parent.set(u,par);       // Traverse the children of    // the current node    for(int child : adj.get(u))    {                 // Recursively call for        // function dfs for the        // child node        if (child != par)            dfs(parent, adj, child, u);    }}   // Function to count the number of// ancestors with values smaller// than that of the current nodestatic void countSmallerAncestors(    ArrayList<ArrayList<Integer>> adj, int n){         // Stores the parent of each node    ArrayList<Integer> parent = new ArrayList<Integer>();    for(int i = 0; i < (int)(1e5); i++)    {        parent.add(0);    }       // Perform the DFS Traversal    dfs(parent, adj, 1, -1);       // Traverse all the nodes    for(int i = 1; i <= n; i++)    {        int node = i;           // Store the number of ancestors        // smaller than node        int cnt = 0;           // Loop until parent[node] != -1        while (parent.get(node) != -1)        {                         // If the condition satisfies,            // increment cnt by 1            if (parent.get(node) < i)                cnt += 1;               node = parent.get(node);        }           // Print the required result        // for the current node        System.out.print(cnt + " ");    }} // Driver codepublic static void main (String[] args){    int N = 6;    ArrayList<ArrayList<Integer>> adj = new ArrayList<ArrayList<Integer>>();    for(int i = 0; i < (int)(1e5); i++)    {        adj.add(new ArrayList<Integer>());    }       // Tree Formation    add_edge(adj, 1, 5);    add_edge(adj, 1, 4);    add_edge(adj, 4, 6);    add_edge(adj, 5, 3);    add_edge(adj, 5, 2);       countSmallerAncestors(adj, N);}} // This code is contributed by avanitrachhadiya2155
# Python3 program for the above approach # Function to add an edge# between nodes u and vdef add_edge(u, v):         global adj    adj[u].append(v)    adj[v].append(u) # Function to perform the DFS Traversal# and store parent of each nodedef dfs(u, par = -1):         global adj, parent         # Store the immediate parent    parent[u] = par     # Traverse the children of    # the current node    for child in adj[u]:                 # Recursively call for        # function dfs for the        # child node        if (child != par):            dfs(child, u) # Function to count the number of# ancestors with values smaller# than that of the current nodedef countSmallerAncestors(n):         global parent, adj         # Stores the parent of each node     # Perform the DFS Traversal    dfs(1)     # Traverse all the nodes    for i in range(1, n + 1):        node = i         # Store the number of ancestors        # smaller than node        cnt = 0         # Loop until parent[node] != -1        while (parent[node] != -1):                         # If the condition satisfies,            # increment cnt by 1            if (parent[node] < i):                cnt += 1             node = parent[node]         # Print the required result        # for the current node        print(cnt, end = " ") # Driver Codeif __name__ == '__main__':         N = 6    adj = [[] for i in range(10**5)]    parent = [0] * (10**5)     # Tree Formation    add_edge(1, 5)    add_edge(1, 4)    add_edge(4, 6)    add_edge(5, 3)    add_edge(5, 2)     countSmallerAncestors(N) # This code is contributed by mohit kumar 29
// C# program for the above approachusing System;using System.Collections.Generic;class GFG {         // Function to add an edge    // between nodes u and v    static void add_edge(List<List<int>> adj, int u, int v)    {        adj[u].Add(v);        adj[v].Add(u);    }          // Function to perform the DFS Traversal    // and store parent of each node    static void dfs(List<int> parent,             List<List<int>> adj,             int u,             int par = -1)    {        // Store the immediate parent        parent[u] = par;              // Traverse the children of        // the current node        foreach(int child in adj[u]) {                  // Recursively call for            // function dfs for the            // child node            if (child != par)                dfs(parent, adj, child, u);        }    }          // Function to count the number of    // ancestors with values smaller    // than that of the current node    static void countSmallerAncestors(        List<List<int>> adj, int n)    {        // Stores the parent of each node        List<int> parent = new List<int>();        for(int i = 0; i < (int)(1e5); i++)        {            parent.Add(0);        }              // Perform the DFS Traversal        dfs(parent, adj, 1);              // Traverse all the nodes        for (int i = 1; i <= n; i++) {                  int node = i;                  // Store the number of ancestors            // smaller than node            int cnt = 0;                  // Loop until parent[node] != -1            while (parent[node] != -1) {                      // If the condition satisfies,                // increment cnt by 1                if (parent[node] < i)                    cnt += 1;                      node = parent[node];            }                  // Print the required result            // for the current node            Console.Write(cnt + " ");        }    }   static void Main() {    int N = 6;    List<List<int>> adj = new List<List<int>>();    for(int i = 0; i < (int)(1e5); i++)    {        adj.Add(new List<int>());    }      // Tree Formation    add_edge(adj, 1, 5);    add_edge(adj, 1, 4);    add_edge(adj, 4, 6);    add_edge(adj, 5, 3);    add_edge(adj, 5, 2);      countSmallerAncestors(adj, N);  }}
<script> // JavaScript program for the above approach // Function to add an edge// between nodes u and vfunction add_edge(adj, u, v){    adj[u].push(v);    adj[v].push(u);} // Function to perform the DFS Traversal// and store parent of each nodefunction dfs(parent, adj, u, par = -1){    // Store the immediate parent    parent[u] = par;     // Traverse the children of    // the current node    adj[u].forEach(child => {                  // Recursively call for        // function dfs for the        // child node        if (child != par)            dfs(parent, adj, child, u);    });} // Function to count the number of// ancestors with values smaller// than that of the current nodefunction countSmallerAncestors(adj, n){    // Stores the parent of each node    var parent = Array(100000).fill(0);     // Perform the DFS Traversal    dfs(parent, adj, 1);     // Traverse all the nodes    for (var i = 1; i <= n; i++) {         var node = i;         // Store the number of ancestors        // smaller than node        var cnt = 0;         // Loop until parent[node] != -1        while (parent[node] != -1) {             // If the condition satisfies,            // increment cnt by 1            if (parent[node] < i)                cnt += 1;             node = parent[node];        }         // Print the required result        // for the current node        document.write( cnt + " ");    }} // Driver Code var N = 6;var adj = Array.from(Array(100000), ()=>Array()); // Tree Formationadd_edge(adj, 1, 5);add_edge(adj, 1, 4);add_edge(adj, 4, 6);add_edge(adj, 5, 3);add_edge(adj, 5, 2);countSmallerAncestors(adj, N);  </script>
0 1 1 1 1 2
 
Time Complexity: O(N2)Auxiliary Space: O(N)
mohit kumar 29
divyeshrabadiya07
avanitrachhadiya2155
itsok
DFS
Mathematical
Recursion
Tree
Mathematical
Recursion
DFS
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Program to print prime numbers from 1 to N.
Segment Tree | Set 1 (Sum of given range)
Modular multiplicative inverse
Count all possible paths from top left to bottom right of a mXn matrix
Fizz Buzz Implementation
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Recursion
Program for Tower of Hanoi
Backtracking | Introduction
Program for Sum of the digits of a given number