Number of isosceles triangles in a binary tree


A binary tree is a data structure in which each node can have two children (at most). These children are known as left and right child respectively. Suppose we are given a parent array representation using which you have to a create a binary tree. The binary tree may have several isosceles triangles. We have to find the total number of possible isosceles triangles in that binary tree.

In this article, we will explore several techniques in C++ to solve this problem.

Understanding the Problem

You are given a parent array. You have to represent it in the form of a binary tree such that the array indexes form the values of the tree nodes while the values in the array gives the parent node for that particular index.

Note that -1 will always be the root parent node. Given below is an array along with its binary tree representation.

Parent array = [0, -1, 3, 1, 1, 2, 2, 3, 4, 4]

Binary Tree −

In any binary tree, we can three types of isosceles triangles −

  • Left isosceles triangle  In this triangle, the apex is a left child of a parent while the vertices forming the base (equal sides of the isosceles triangle) are the left children of the apex. The children can be both direct or indirect. In the above tree, we have two such isosceles triangles- (2, 6, 3), (3, 7, 1).

  • Right isosceles triangle  In this triangle, the apex is a right child of a parent while the vertices forming the base are the right children of the apex. The children can be both direct or indirect. In the above tree, we have only one such isosceles triangle (4, 1, 8).

  • Balanced isosceles triangle  In this triangle, the vertices forming the base are the left and right child of the apex node. In the above tree, we have five such isosceles triangles (1, 3, 4), (3, 2, 7), (4, 8, 9), (2, 5, 6), (1, 2, 9)

Hence, we have total 8 isosceles triangles for the above binary tree.

Using Depth First Search Traversal

Depth first search (DFS) is a method to traverse through all the nodes of a tree in a depth ward manner. It starts from the root node and moves to each of the branches and then backtracks.

  • First, we have used DFS to traverse over each node of the binary tree which is converted into a graph so that each node is represented adjacent to each other. This makes the traversal easier.

  • For each node, we check whether it has any children or not. After checking, it sorts them using the sort(node[x].begin(), node[x].end()) function.

  • Next, we check whether the current node is the left or right successor of its respective parent or not. We use the DFS function recursively for all the nodes of the binary tree.

  • If the current node has two children (direct or indirect), we check the possibility of having isosceles triangles by counting the edges between them. We will find the edges between them by the graph function given in the code below.

  • At last, we count the total number of isosceles triangles by adding all the possible triangles from different positions.

Example

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;

#define MAX int(1e5)
vector < int > * node;
int right_down[MAX];
int right_up[MAX];
int left_down[MAX];
int left_up[MAX];

// DFS traversal over a node
void DFS(int x, int * parent) {
   // Check if adjacent nodes are present for node x
   if (node[x].size() != 0)
      sort(node[x].begin(), node[x].end());

   // Check whether the node has a parent node
   if (parent[x] != -1) {
      int indexOfParent = parent[x];
      int childrenCount = node[indexOfParent].size();

      if (childrenCount > 1) {
         int parentFirstChild = node[indexOfParent][0];

         // Check if current node is left node of the parent
         if (x == parentFirstChild) {
            right_up[x] += right_up[indexOfParent] + 1;
            // Check if current node is right node of the parent  
         } else {
            left_up[x] += left_up[indexOfParent] + 1;
         }
      } else {
         right_up[x] += right_up[indexOfParent] + 1;
      }
   }

   // Iterate over children of current node  
   for (int i = 0; i < node[x].size(); ++i) {
      int y = node[x][i];
      DFS(y, parent);

      // left child of current node
      if (i == 0) {
         left_down[x] += left_down[y] + 1;
      }
      // right child of current node
      else {
         right_down[x] += right_down[y] + 1;
      }
   }
}

int graph(int * parent, int N) {
   int rootNode;
   node = new vector < int > [N];

   for (int i = 0; i < N; ++i) {
      if (parent[i] != -1) {
         node[parent[i]].push_back(i);
      } else {
         rootNode = i;
      }

      left_up[i] = 0;
      right_up[i] = 0;
      left_down[i] = 0;
      right_down[i] = 0;
   }
   return rootNode;
}

int main() {
   int N = 10;
   int parent[] = { 0, -1, 3, 1, 1, 2, 2, 3, 4, 4 };
   int rootNode = graph(parent, N);
   DFS(rootNode, parent);
   int count = 0;
   // Counting the total 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 binary tree are " <<
      count;
   return 0;
}

Output

Number of isosceles triangles in the binary tree are 8

Conclusion

We have discussed about how to find the total number of isosceles triangles in a binary tree when you are given a parent array. We can do this by using depth first search which allows us to traverse through a binary tree.

Updated on: 12-Jul-2023

69 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements