Skip to content
Related Articles

Related Articles

Improve Article

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

  • Last Updated : 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  2
Output: 0 1 1 1 1 2
Explanation: 
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
                    \
                     4
Output: 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.
  • 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.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to add an edge
// between nodes u and v
void 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 node
void 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 node
void 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 Code
int 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




// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
     
// Function to add an edge
// between nodes u and v
static 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 node
static 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 node
static 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 code
public 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




# Python3 program for the above approach
 
# Function to add an edge
# between nodes u and v
def 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 node
def 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 node
def 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 Code
if __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#




// C# program for the above approach
using 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);
  }
}

Javascript




<script>
 
// JavaScript program for the above approach
 
// Function to add an edge
// between nodes u and v
function add_edge(adj, u, v)
{
    adj[u].push(v);
    adj[v].push(u);
}
 
// Function to perform the DFS Traversal
// and store parent of each node
function 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 node
function 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 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>
Output: 
0 1 1 1 1 2

 

Time Complexity: O(N2)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :