Number of Isosceles triangles in a binary tree

Pre-Requisites: Depth First Search | Parent Array Representation

Given a parent array representation of a binary tree, we need to find the number of Isosceles triangles in the binary tree.

Consider a parent array representing a binary tree:
Parent Array:
Parent Array

Given below is the tree representation of the given parent array.
Binary Tree:
Binary Tree

There are three types of isosceles triangles which can be found inside a binary tree. These three different types of isosceles triangles can be handled as three different cases.



Case 1: Apex(Vertex against the base sharing equal sides) has two successors(both direct/indirect).
This case can be represented as:
Down Triangle
In the given tree, there are 6 such isosceles triangles i.e; (0, 1, 2), (0, 3, 6), (1, 3, 4), (1, 7, 9), (4, 8, 9), (2, 5, 6)

Psuedo Code: count += min(left_down[i], right_down[i]);

Case 2: Apex has a left successor(direct/indirect) and apex itself is a right successor(direct/indirect) of its parent.
This case can be represented as:

In the given tree, there are 2 such isosceles triangles i.e; (1, 8, 4), (0, 5, 2)

Psuedo Code: count += min(left_down[i], left_up[i]);

Case 3: Apex has a right successor(direct/indirect) and apex itself is a left successor(direct/indirect) of its parent.
This case can be represented as:

In the given tree, there is 1 such isosceles triangle i.e; (0, 1, 4)

Psuedo Code: count += min(right_down[i], right_up[i]);

Psuedo Code legend:
left_down[i] -> maximum distance of ith node from its farthest left successor
right_down[i] -> maximum distance of ith node from its farthest right successor
left_up[i] -> maximum distance of ith node from its farthest left predecessor
right_up[i] -> maximum distance of ith node from its farthest right predecessor

Below is the implementation to calculate the number of isosceles triangles present in a given binary tree:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

/* C++ program for calculating number of 
isosceles triangles present in a binary tree */
#include <bits/stdc++.h>
using namespace std;
  
#define MAX_SZ int(1e5)
  
/* Data Structure used to store 
   Binary Tree in form of Graph */
vector<int>* graph;
  
// Data varirables
int right_down[MAX_SZ];
int left_down[MAX_SZ];
int right_up[MAX_SZ];
int left_up[MAX_SZ];
  
/* Utility function used to 
   start a DFS traversal over a node */
void DFS(int u, int* parent)
{
  
    if (graph[u].size() != 0)
        sort(graph[u].begin(), graph[u].end());
  
    if (parent[u] != -1) {
        if (graph[parent[u]].size() > 1) {
            /* check if current node is 
                                left child of its parent */
            if (u == graph[parent[u]][0]) {
                right_up[u] += right_up[parent[u]] + 1;
            }
            // current node is right child of its parent
            else {
                left_up[u] += left_up[parent[u]] + 1;
            }
        }
        /* check if current node is left and 
                            only child of its parent */
        else {
            right_up[u] += right_up[parent[u]] + 1;
        }
    }
    for (int i = 0; i < graph[u].size(); ++i) {
  
        int v = graph[u][i];
  
        // iterating over subtree
        DFS(v, parent);
  
        // left child of current node
        if (i == 0) {
            left_down[u] += left_down[v] + 1;
        }
        // right child of current node
        else {
            right_down[u] += right_down[v] + 1;
        }
    }
}
  
/* utility function used to generate 
                graph from parent array */
int generateGraph(int* parent, int n)
{
  
    int root;
  
    graph = new vector<int>[n];
  
    // Generating graph from parent array
    for (int i = 0; i < n; ++i) {
  
        // check for non-root node
        if (parent[i] != -1) {
            /* creating an edge from node with number
             parent[i] to node with number i */
            graph[parent[i]].push_back(i);
        }
        // initializing root
        else {
            root = i;
        }
  
        // Initializing necessary data variables
        left_up[i] = 0;
        right_up[i] = 0;
        left_down[i] = 0;
        right_down[i] = 0;
    }
    // root of the binary tree
    return root;
}
  
// Driver Function
int main()
{
  
    int n = 10;
  
    /* Parent array used for storing 
       parent of each node */
    int parent[] = { -1, 0, 0, 1, 1, 2, 2, 3, 4, 4 };
  
    /* generateGraph() function generates a graph a 
       returns root of the graph which can be used for
       starting DFS traversal */
    int root = generateGraph(parent, n);
  
    // triggering dfs for traversal over graph
    DFS(root, parent);
  
    int count = 0;
  
    // Calculation of number of isosceles triangles
    for (int i = 0; i < n; ++i) {
        count += min(right_down[i], right_up[i]);
        count += min(left_down[i], left_up[i]);
        count += min(left_down[i], right_down[i]);
    }
  
    cout << "Number of isosceles triangles "
         << "in the given binary tree are " << count;
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

/* JAVA program for calculating number of 
isosceles triangles present in a binary tree */
  
import java.io.*;
import java.util.*;
  
@SuppressWarnings("unchecked")
class Isosceles_triangles {
  
    static int MAX_SZ = (int)1e5;
  
    /* Data Structure used to store 
       Binary Tree in form of Graph */
    static ArrayList<Integer>[] graph;
  
    // Data varirables
    static int[] right_down = new int[MAX_SZ];
    static int[] left_down = new int[MAX_SZ];
    static int[] right_up = new int[MAX_SZ];
    static int[] left_up = new int[MAX_SZ];
  
    /* Utility function used to 
       start a DFS traversal over a node */
    public static void DFS(int u, int[] parent)
    {
  
        if (graph[u] != null)
            Collections.sort(graph[u]);
  
        if (parent[u] != -1) {
            if (graph[parent[u]].size() > 1) {
                /* check if current node is 
                                left child of its parent */
                if (u == graph[parent[u]].get(0)) {
                    right_up[u] += right_up[parent[u]] + 1;
                }
                // current node is right child of its parent
                else {
                    left_up[u] += left_up[parent[u]] + 1;
                }
            }
            /* check if current node is left and 
                                only child of its parent */
            else {
                right_up[u] += right_up[parent[u]] + 1;
            }
        }
  
        if (graph[u] == null)
            return;
  
        for (int i = 0; i < graph[u].size(); ++i) {
  
            int v = graph[u].get(i);
  
            // iterating over subtree
            DFS(v, parent);
  
            // left child of current node
            if (i == 0) {
                left_down[u] += left_down[v] + 1;
            }
            // right child of current node
            else {
                right_down[u] += right_down[v] + 1;
            }
        }
    }
  
    static int min(Integer a, Integer b)
    {
        return (a < b) ? a : b;
    }
  
    /* utility function used to generate 
                    graph from parent array */
    public static int generateGraph(int[] parent, int n)
    {
  
        int root = -1;
  
        graph = (ArrayList<Integer>[]) new ArrayList[n];
  
        // Generating graph from parent array
        for (int i = 0; i < n; ++i) {
  
            // check for non-root node
            if (parent[i] != -1) {
                /* creating an edge from node with number
                 parent[i] to node with number i */
                if (graph[parent[i]] == null) {
                    graph[parent[i]] = new ArrayList<Integer>();
                }
                graph[parent[i]].add(i);
                // System.out.println(graph);
            }
            // initializing root
            else {
                root = i;
            }
  
            // Initializing necessary data variables
            left_up[i] = 0;
            right_up[i] = 0;
            left_down[i] = 0;
            right_down[i] = 0;
        }
        // root of the binary tree
        return root;
    }
  
    // Driver Function
    public static void main(String[] args)
    {
  
        int n = 10;
  
        /* Parent array used for storing 
           parent of each node */
        int[] parent = new int[] { -1, 0, 0, 1, 1, 2, 2, 3, 4, 4 };
  
        /* generateGraph() function generates a graph a 
           returns root of the graph which can be used for
           starting DFS traversal */
        int root = generateGraph(parent, n);
  
        // System.exit(0);
  
        // triggering dfs for traversal over graph
        DFS(root, parent);
  
        int count = 0;
  
        // Calculation of number of isosceles triangles
        for (int i = 0; i < n; ++i) {
            count += min(right_down[i], right_up[i]);
            count += min(left_down[i], left_up[i]);
            count += min(left_down[i], right_down[i]);
        }
        System.out.println("Number of isosceles triangles "
                           + "in the given binary tree are "
                           + Integer.toString(count));
  
        System.exit(0);
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

''' Python3 program for calculating number of 
isosceles triangles present in a binary tree '''
  
MAX_SZ = int(1e5)
  
''' Data Structure used to store 
  Binary Tree in form of Graph '''
graph = {}
  
# Data varirables 
right_down = MAX_SZ*[0]
left_down = MAX_SZ*[0]
right_up = MAX_SZ*[0]
left_up = MAX_SZ*[0]
  
''' Utility function used to 
    start a DFS traversal over a node '''
def DFS(u, parent):
  
    if u in graph:
        graph[u].sort()
  
    if parent[u] != -1:
        if u in graph and len(graph[parent[u]]) > 1:
            ''' check if current node is 
                            left child of its parent '''
            if u == graph[parent[u]][0] :
                right_up[u] += right_up[parent[u]] + 1
              
            # current node is right child of its parent
            else:
                left_up[u] += left_up[parent[u]] + 1
  
        else :
            ''' check if current node is left and 
                            only child of its parent '''
            right_up[u] += right_up[parent[u]] + 1
          
    if u in graph:
        for i in range(0, len(graph[u])):
  
            v = graph[u][i]
  
            # iterating over subtree
            DFS(v, parent)
  
            # left child of current node
            if i == 0:
                left_down[u] += left_down[v] + 1;
              
            # right child of current node
            else:
                right_down[u] += right_down[v] + 1;
  
  
''' utility function used to generate 
                graph from parent array '''
def generateGraph(parent, n):
      
    root = -1
  
    # Generating graph from parent array
    for i in range(0, n):
          
        # check for non-root node
        if parent[i] != -1:
            ''' creating an edge from node with number
             parent[i] to node with number i '''
            if parent[i] not in graph:
                graph[parent[i]] = [i]
            else :
                graph[parent[i]].append(i)
          
        # initializing root
        else :
            root = i
      
    # root of the binary tree
    return root;
  
# Driver Function
if __name__ == '__main__':
  
    n = 10
  
    ''' Parent array used for storing 
       parent of each node '''
    parent = [-1, 0, 0, 1, 1, 2, 2, 3, 4, 4]
  
    ''' generateGraph() function generates a graph a 
    returns root of the graph which can be used for
     starting DFS traversal '''
    root = generateGraph(parent, n)
          
    # triggering dfs for traversal over graph
    DFS(root, parent)
  
    count = 0
  
    # Calculation of number of isosceles triangles
    for i in range(0, n):
        count += min(right_down[i], right_up[i])
        count += min(left_down[i], left_up[i])
        count += min(left_down[i], right_down[i])
      
    print("Number of isosceles triangles " 
            + "in the given binary tree are " 
            + str(count))

chevron_right


Output:

Number of isosceles triangles in the given binary tree are 9

Time Complexity : O(n)
Auxiliary Space : O(n)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.