Construct Ancestor Matrix from a Given Binary Tree - GeeksforGeeks

11 Jun, 2021
Given a Binary Tree where all values are from 0 to n-1. Construct an ancestor matrix mat[n][n]. Ancestor matrix is defined as below.
mat[i][j] = 1 if i is ancestor of j
mat[i][j] = 0, otherwise
Examples: 
Input: Root of below Binary Tree.
          0
        /   \
       1     2
Output: 0 1 1
        0 0 0 
        0 0 0 

Input: Root of below Binary Tree.
           5
        /    \
       1      2
      /  \    /
     0    4  3
Output: 0 0 0 0 0 0 
        1 0 0 0 1 0 
        0 0 0 1 0 0 
        0 0 0 0 0 0 
        0 0 0 0 0 0 
        1 1 1 1 1 0
We strongly recommend you to minimize your browser and try this yourself first.
Method 1The idea is to traverse the tree. While traversing, keep track of ancestors in an array. When we visit a node, we add it to ancestor array and consider corresponding row in adjacency matrix. We mark all ancestors in its row as 1. Once a node and all its children are processed, we remove the node from ancestor array.
Below is the implementation of above idea. 
C++
Java
Python3
C#
Javascript
// C++ program to construct ancestor matrix for// given tree.#include<bits/stdc++.h>using namespace std;#define MAX 100 /* A binary tree node */struct Node{    int data;    Node *left, *right;}; // Creating a global boolean matrix for simplicitybool mat[MAX][MAX]; // anc[] stores all ancestors of current node.  This// function fills ancestors for all nodes.// It also returns size of tree.  Size of tree is// used to print ancestor matrix.int ancestorMatrixRec(Node *root, vector<int> &anc){    /* base case */    if (root == NULL) return 0;;     // Update all ancestors of current node    int data = root->data;    for (int i=0; i<anc.size(); i++)       mat[anc[i]][data] = true;     // Push data to list of ancestors    anc.push_back(data);     // Traverse left and right subtrees    int l = ancestorMatrixRec(root->left, anc);    int r = ancestorMatrixRec(root->right, anc);     // Remove data from list the list of ancestors    // as all descendants of it are processed now.    anc.pop_back();     return l+r+1;} // This function mainly calls ancestorMatrixRec()void ancestorMatrix(Node *root){    // Create an empty ancestor array    vector<int> anc;     // Fill ancestor matrix and find size of    // tree.    int n = ancestorMatrixRec(root, anc);     // Print the filled values    for (int i=0; i<n; i++)    {        for (int j=0; j<n; j++)            cout << mat[i][j] << " ";        cout << endl;    }} /* Helper function to create a new node */Node* newnode(int data){    Node* node = new Node;    node->data = data;    node->left = node->right = NULL;    return (node);} /* Driver program to test above functions*/int main(){    /* Construct the following binary tree                5              /   \            1      2          /  \    /         0    4  3    */    Node *root        = newnode(5);    root->left        = newnode(1);    root->right       = newnode(2);    root->left->left  = newnode(0);    root->left->right = newnode(4);    root->right->left = newnode(3);     ancestorMatrix(root);     return 0;}
// Java Program to construct ancestor matrix for a given treeimport java.util.*; class GFG{    // ancestorMatrix function to populate the matrix of    public static void ancestorMatrix(Node root ,                                    int matrix[][],int size)    {                 // base case:        if (root==null)        return ;                 // call recursively for a preorder {left}        ancestorMatrix(root.left, matrix, size);                 // call recursively for preorder {right}        ancestorMatrix(root.right, matrix, size);                 // here we will reach the root node automatically        // try solving on pen and paper                 if (root.left != null)        {            // make the current node as parent of its children node            matrix[root.data][root.left.data] = 1;                         // iterate through all the columns of children node            // all nodes which are children to            // children of root node will also            // be children of root node            for (int i = 0; i < size; i++)            {                // if children of root node is a parent                // of someone (i.e 1) then make that node                // as children of root also                if (matrix[root.left.data][i] == 1)                matrix[root.data][i] = 1;            }        }                 // same procedure followed for right node as well        if (root.right != null)        {            matrix[root.data][root.right.data] = 1;                         for (int i = 0; i < size; i++)            {                if (matrix[root.right.data][i]==1)                matrix[root.data][i] = 1;            }        }                          }         // Driver program to test the program    public static void main(String[] args)    {                 // construct the binary tree as follows        Node tree_root = new Node(5);        tree_root.left = new Node (1);        tree_root.right = new Node(2);        tree_root.left.left = new Node(0);        tree_root.left.right = new Node(4);        tree_root.right.left = new Node(3);                 // size of matrix        int size = 6;        int matrix [][] = new int[size][size];                 ancestorMatrix(tree_root, matrix, size);                 for (int i = 0; i < size; i++)        {            for (int j = 0; j < size; j++)            {                System.out.print(matrix[i][j]+" ");            }            System.out.println();        }    }         // node class for tree node    static class Node    {        public int data ;        public Node left ,right;        public Node (int data)        {            this.data = data;            this.left = this.right = null;        }    }} // This code is contributed by Sparsh Singhal
# Python3 program to construct ancestor# matrix for given tree. class newnode:    def __init__(self, data):        self.data = data        self.left = self.right = None         # anc[] stores all ancestors of current node.# This function fills ancestors for all nodes.# It also returns size of tree. Size of tree # is used to print ancestor matrix.def ancestorMatrixRec(root, anc):    global mat, MAX         # base case    if root == None:        return 0     # Update all ancestors of current node    data = root.data    for i in range(len(anc)):        mat[anc[i]][data] = 1     # Push data to list of ancestors    anc.append(data)     # Traverse left and right subtrees    l = ancestorMatrixRec(root.left, anc)    r = ancestorMatrixRec(root.right, anc)     # Remove data from list the list of ancestors    # as all descendants of it are processed now.    anc.pop(-1)     return l + r + 1 # This function mainly calls ancestorMatrixRec()def ancestorMatrix(root):         # Create an empty ancestor array    anc = []     # Fill ancestor matrix and find    # size of tree.    n = ancestorMatrixRec(root, anc)     # Print the filled values    for i in range(n):        for j in range(n):            print(mat[i][j], end = " ")        print() # Driver CodeMAX = 100mat = [[0] * MAX for i in range(MAX)] # Construct the following binary tree#         5#         / \#     1     2#     / \ /#     0 4 3root = newnode(5)root.left = newnode(1)root.right = newnode(2)root.left.left = newnode(0)root.left.right = newnode(4)root.right.left = newnode(3) ancestorMatrix(root) # This code is contributed by PranchalK
// C# Program to construct ancestor matrix for a given treeusing System; class GFG{    // ancestorMatrix function to populate the matrix of    public static void ancestorMatrix(Node root,                        int [,]matrix, int size)    {         // base case:        if (root == null)        {            return;        }         // call recursively for a preorder {left}        ancestorMatrix(root.left, matrix, size);         // call recursively for preorder {right}        ancestorMatrix(root.right, matrix, size);         // here we will reach the root node automatically        // try solving on pen and paper        if (root.left != null)        {            // make the current node as parent of its children node            matrix[root.data,root.left.data] = 1;             // iterate through all the columns of children node            // all nodes which are children to            // children of root node will also            // be children of root node            for (int i = 0; i < size; i++)            {                // if children of root node is a parent                // of someone (i.e 1) then make that node                // as children of root also                if (matrix[root.left.data,i] == 1)                {                    matrix[root.data,i] = 1;                }            }        }         // same procedure followed for right node as well        if (root.right != null)        {            matrix[root.data,root.right.data] = 1;             for (int i = 0; i < size; i++)            {                if (matrix[root.right.data,i] == 1)                {                    matrix[root.data,i] = 1;                }            }        }     }     // Driver code    public static void Main(String[] args)    {         // construct the binary tree as follows        Node tree_root = new Node(5);        tree_root.left = new Node(1);        tree_root.right = new Node(2);        tree_root.left.left = new Node(0);        tree_root.left.right = new Node(4);        tree_root.right.left = new Node(3);         // size of matrix        int size = 6;        int [,]matrix = new int[size,size];         ancestorMatrix(tree_root, matrix, size);         for (int i = 0; i < size; i++)        {            for (int j = 0; j < size; j++)            {                Console.Write(matrix[i,j] + " ");            }            Console.WriteLine();        }    }     // node class for tree node    public class Node    {         public int data;        public Node left, right;         public Node(int data)        {            this.data = data;            this.left = this.right = null;        }    }} // This code is contributed by 29AjayKumar
<script> class Node{    constructor(data)    {        this.data=data;        this.left = this.right = null;    }} function ancestorMatrixRec(root ,anc){    // base case:        if (root==null)            return 0;                 let data = root.data;        for(let i=0;i<anc.length;i++)        {            matrix[anc[i]][data] = 1;        }        //document.write(data+"<br>")        // Push data to list of ancestors    anc.push(data);      // Traverse left and right subtrees    let l = ancestorMatrixRec(root.left, anc);    let r = ancestorMatrixRec(root.right, anc);      // Remove data from list the list of ancestors    // as all descendants of it are processed now.    anc.pop()    return l + r + 1;} function ancestorMatrix(root){    let anc = [];    let n = ancestorMatrixRec(root, anc);    for (let i = 0; i < n; i++)        {            for (let j = 0; j < n; j++)            {                document.write(matrix[i][j]+" ");            }            document.write("<br>");        } }  // construct the binary tree as follows        let tree_root = new Node(5);        tree_root.left = new Node (1);        tree_root.right = new Node(2);        tree_root.left.left = new Node(0);        tree_root.left.right = new Node(4);        tree_root.right.left = new Node(3);                  // size of matrix        let size = 100;        let matrix = new Array(size);        for(let i=0;i<size;i++)        {            matrix[i]=new Array(size);            for(let j=0;j<size;j++)            {                matrix[i][j]=0;            }        }                  ancestorMatrix(tree_root);                     // This code is contributed by rag2127</script>
Output: 
0 0 0 0 0 0 
1 0 0 0 1 0 
0 0 0 1 0 0 
0 0 0 0 0 0 
0 0 0 0 0 0 
1 1 1 1 1 0
Time complexity of above solution is O(n2).
Method 2This method doesn’t use any auxiliary space to store values in the vector. Create a 2D matrix( say M) of the given size. Now the idea is to traverse the tree in PreOrder. While traversing, keep track of the last ancestor. When we visit a node, if the node is NULL return, else assign M[lastAncestorValue][currentNodeValue]=1. Through this, we have the Matrix(M) which keeps tracks of the Lowest Ancestor, Now by applying transitive closure to this Matrix(M), we get the required result.
Below is the implementation of the above idea.
C++
Java
Python3
C#
Javascript
// C++ program to construct ancestor matrix for// given tree.#include<bits/stdc++.h>using namespace std;#define size 6 int M[size][size]={0}; /* A binary tree node */struct Node{    int data;    Node *left, *right;}; /* Helper function to create a new node */Node* newnode(int data){    Node* node = new Node;    node->data = data;    node->left = node->right = NULL;    return (node);} void printMatrix(){        for(int i=0;i<size;i++){            for(int j=0;j<size;j++)                cout<<M[i][j]<<" ";            cout<<endl;        }        }//First PreOrder Traversalvoid MatrixUtil(Node *root,int index){             if(root==NULL)return;             int preData=root->data;                     //Since there is no ancestor for root node,        // so we doesn't assign it's value as 1                   if(index==-1)index=root->data;        else  M[index][preData]=1;            MatrixUtil(root->left,preData);    MatrixUtil(root->right,preData);} void Matrix(Node *root){    // Call Func MatrixUtil    MatrixUtil(root,-1);              //Applying Transitive Closure for the given Matrix    for(int i=0;i<size;i++){        for (int j = 0;j< size; j++) {            for(int k=0;k<size;k++)                M[j][k]=M[j][k]||(M[j][i]&&M[i][k]);                     }             }         //Printing Matrix    printMatrix();      }/* Driver program to test above functions*/int main(){    Node *root     = newnode(5);    root->left     = newnode(1);    root->right     = newnode(2);    root->left->left = newnode(0);    root->left->right = newnode(4);    root->right->left = newnode(3);     Matrix(root);          return 0;}
// Java program to conancestor matrix for// given tree. import java.util.*;class GFG{  static final int size = 6;   static int [][]M = new int[size][size];   /* A binary tree node */  static class Node  {    int data;    Node left, right;  };   /* Helper function to create a new node */  static Node newnode(int data)  {    Node node = new Node();    node.data = data;    node.left = node.right = null;    return (node);  }   static void printMatrix()  {    for(int i = 0; i < size; i++)    {      for(int j = 0; j < size; j++)        System.out.print(M[i][j] + " ");      System.out.println();    }         }   // First PreOrder Traversal  static void MatrixUtil(Node root, int index)  {           if(root == null)return;      int preData = root.data;     // Since there is no ancestor for root node,    // so we doesn't assign it's value as 1               if(index == -1)index = root.data;    else  M[index][preData] = 1;        MatrixUtil(root.left, preData);    MatrixUtil(root.right, preData);  }   static void Matrix(Node root)  {     // Call Func MatrixUtil    MatrixUtil(root, -1);     // Applying Transitive Closure for the given Matrix    for(int i = 0; i < size; i++)    {      for (int j = 0; j < size; j++)      {        for(int k = 0; k < size; k++)        {          if(M[j][k] == 1)            M[j][k] = 1;          else if((M[j][i] == 1 && M[i][k] == 1))            M[j][k] = 1;        }      }     }     // Printing Matrix    printMatrix();     }   /* Driver program to test above functions*/  public static void main(String[] args)  {    Node root = newnode(5);    root.left = newnode(1);    root.right = newnode(2);    root.left.left = newnode(0);    root.left.right = newnode(4);    root.right.left = newnode(3);    Matrix(root);  }} // This code is contributed by Rajput-Ji
# Python3 program to construct ancestor# matrix for given tree.size = 6  M = [[0 for j in range(size)]        for i in range(size)] # A binary tree nodeclass Node:         def __init__(self, data):                 self.left = None        self.right = None        self.data = data         # Helper function to create a new nodedef newnode(data):     temp = Node(data)         return temp def printMatrix():         for i in range(size):        for j in range(size):            print(M[i][j], end = ' ')                 print()      # First PreOrder Traversaldef MatrixUtil(root, index):         if (root == None):        return          preData = root.data                  # Since there is no ancestor for    # root node, so we doesn't assign    # it's value as 1               if (index == -1):        index = root.data    else:        M[index][preData] = 1             MatrixUtil(root.left, preData)    MatrixUtil(root.right, preData) def Matrix(root):         # Call Func MatrixUtil    MatrixUtil(root, -1)          # Applying Transitive Closure    # for the given Matrix    for i in range(size):        for j in range(size):            for k in range(size):                M[j][k] = (M[j][k] or                          (M[j][i] and                           M[i][k]))          # Printing Matrix    printMatrix()  # Driver codeif __name__=="__main__":         root = newnode(5)    root.left = newnode(1)    root.right = newnode(2)    root.left.left = newnode(0)    root.left.right = newnode(4)    root.right.left = newnode(3)      Matrix(root)      # This code is contributed by rutvik_56
// C# program to conancestor matrix for// given tree. using System;class GFG{  static readonly int size = 6;  static int [,]M = new int[size, size];   /* A binary tree node */  public     class Node    {      public         int data;      public         Node left, right;    };   /* Helper function to create a new node */  static Node newnode(int data)  {    Node node = new Node();    node.data = data;    node.left = node.right = null;    return (node);  }   static void printMatrix()  {    for(int i = 0; i < size; i++)    {      for(int j = 0; j < size; j++)        Console.Write(M[i, j] + " ");      Console.WriteLine();    }         }   // First PreOrder Traversal  static void MatrixUtil(Node root, int index)  {           if(root == null)      return;      int preData = root.data;     // Since there is no ancestor for root node,    // so we doesn't assign it's value as 1               if(index == -1)index = root.data;    else  M[index,preData] = 1;        MatrixUtil(root.left, preData);    MatrixUtil(root.right, preData);  }   static void Matrix(Node root)  {     // Call Func MatrixUtil    MatrixUtil(root, -1);     // Applying Transitive Closure for the given Matrix    for(int i = 0; i < size; i++)    {      for (int j = 0; j < size; j++)      {        for(int k = 0; k < size; k++)        {          if(M[j, k] == 1)            M[j, k] = 1;          else if((M[j, i] == 1 && M[i, k] == 1))            M[j, k] = 1;        }      }    }     // Printing Matrix    printMatrix();     }   /* Driver code*/  public static void Main(String[] args)  {    Node root = newnode(5);    root.left = newnode(1);    root.right = newnode(2);    root.left.left = newnode(0);    root.left.right = newnode(4);    root.right.left = newnode(3);    Matrix(root);  }} // This code is contributed by Rajput-Ji
<script>// javascript program to conancestor matrix for// given tree.       var size = 6;      var M = Array(size).fill().map(()=>Array(size).fill(0));     /* A binary tree node */     class Node {            constructor(val) {                this.data = val;                this.left = null;                this.right = null;            }        }     /* Helper function to create a new node */    function newnode(data) {var node = new Node();        node.data = data;        node.left = node.right = null;        return (node);    }     function printMatrix() {        for (i = 0; i < size; i++) {            for (j = 0; j < size; j++)                document.write(M[i][j] + " ");            document.write("<br/>");        }    }     // First PreOrder Traversal    function MatrixUtil(root , index) {        if (root == null)            return;        var preData = root.data;         // Since there is no ancestor for root node,        // so we doesn't assign it's value as 1        if (index == -1)            index = root.data;        else            M[index][preData] = 1;         MatrixUtil(root.left, preData);        MatrixUtil(root.right, preData);    }     function Matrix(root) {         // Call Func MatrixUtil        MatrixUtil(root, -1);         // Applying Transitive Closure for the given Matrix        for (i = 0; i < size; i++)        {            for (j = 0; j < size; j++) {                for (k = 0; k < size; k++) {                    if (M[j][k] == 1)                        M[j][k] = 1;                    else if ((M[j][i] == 1 && M[i][k] == 1))                        M[j][k] = 1;                }            }        }         // Printing Matrix        printMatrix();    }     /* Driver program to test above functions */           var root = newnode(5);        root.left = newnode(1);        root.right = newnode(2);        root.left.left = newnode(0);        root.left.right = newnode(4);        root.right.left = newnode(3);        Matrix(root); // This code is contributed by gauravrajput1</script>
Output: 
0 0 0 0 0 0 
1 0 0 0 1 0 
0 0 0 1 0 0 
0 0 0 0 0 0 
0 0 0 0 0 0 
1 1 1 1 1 0
How to do reverse – construct tree from ancestor matrix? Construct tree from ancestor matrix
This article is contributed by Dheeraj Gupta. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
PranchalKatiyar
sparsh singhal
29AjayKumar
ssatyanand7
rutvik_56
Rajput-Ji
GauravRajput1
rag2127
Matrix
Tree
Matrix
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Divide and Conquer | Set 5 (Strassen's Matrix Multiplication)
Program to multiply two matrices
Min Cost Path | DP-6
The Celebrity Problem
Rotate a matrix by 90 degree in clockwise direction without using any extra space
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)