Construct Ancestor Matrix from a Given Binary Tree
Last Updated :
27 Aug, 2022
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 1: The 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 the corresponding row in the 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++
#include<bits/stdc++.h>
using namespace std;
#define MAX 100
struct Node
{
int data;
Node *left, *right;
};
bool mat[MAX][MAX];
int ancestorMatrixRec(Node *root, vector< int > &anc)
{
if (root == NULL) return 0;;
int data = root->data;
for ( int i=0; i<anc.size(); i++)
mat[anc[i]][data] = true ;
anc.push_back(data);
int l = ancestorMatrixRec(root->left, anc);
int r = ancestorMatrixRec(root->right, anc);
anc.pop_back();
return l+r+1;
}
void ancestorMatrix(Node *root)
{
vector< int > anc;
int n = ancestorMatrixRec(root, anc);
for ( int i=0; i<n; i++)
{
for ( int j=0; j<n; j++)
cout << mat[i][j] << " " ;
cout << endl;
}
}
Node* newnode( int data)
{
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return (node);
}
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);
ancestorMatrix(root);
return 0;
}
|
Java
import java.util.*;
class GFG
{
public static void ancestorMatrix(Node root ,
int matrix[][], int size)
{
if (root== null )
return ;
ancestorMatrix(root.left, matrix, size);
ancestorMatrix(root.right, matrix, size);
if (root.left != null )
{
matrix[root.data][root.left.data] = 1 ;
for ( int i = 0 ; i < size; i++)
{
if (matrix[root.left.data][i] == 1 )
matrix[root.data][i] = 1 ;
}
}
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 ;
}
}
}
public static void main(String[] args)
{
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 );
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();
}
}
static class Node
{
public int data ;
public Node left ,right;
public Node ( int data)
{
this .data = data;
this .left = this .right = null ;
}
}
}
|
Python3
class newnode:
def __init__( self , data):
self .data = data
self .left = self .right = None
def ancestorMatrixRec(root, anc):
global mat, MAX
if root = = None :
return 0
data = root.data
for i in range ( len (anc)):
mat[anc[i]][data] = 1
anc.append(data)
l = ancestorMatrixRec(root.left, anc)
r = ancestorMatrixRec(root.right, anc)
anc.pop( - 1 )
return l + r + 1
def ancestorMatrix(root):
anc = []
n = ancestorMatrixRec(root, anc)
for i in range (n):
for j in range (n):
print (mat[i][j], end = " " )
print ()
MAX = 100
mat = [[ 0 ] * MAX for i in range ( MAX )]
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)
|
C#
using System;
class GFG
{
public static void ancestorMatrix(Node root,
int [,]matrix, int size)
{
if (root == null )
{
return ;
}
ancestorMatrix(root.left, matrix, size);
ancestorMatrix(root.right, matrix, size);
if (root.left != null )
{
matrix[root.data,root.left.data] = 1;
for ( int i = 0; i < size; i++)
{
if (matrix[root.left.data,i] == 1)
{
matrix[root.data,i] = 1;
}
}
}
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;
}
}
}
}
public static void Main(String[] args)
{
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);
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();
}
}
public class Node
{
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
this .left = this .right = null ;
}
}
}
|
Javascript
<script>
class Node
{
constructor(data)
{
this .data=data;
this .left = this .right = null ;
}
}
function ancestorMatrixRec(root ,anc)
{
if (root== null )
return 0;
let data = root.data;
for (let i=0;i<anc.length;i++)
{
matrix[anc[i]][data] = 1;
}
anc.push(data);
let l = ancestorMatrixRec(root.left, anc);
let r = ancestorMatrixRec(root.right, anc);
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>" );
}
}
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);
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);
</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).
Auxiliary Space: O(n2), since n2 extra space has been taken.
Method 2:
This 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++
#include<bits/stdc++.h>
using namespace std;
#define size 6
int M[size][size]={0};
struct Node
{
int data;
Node *left, *right;
};
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;
}
}
void MatrixUtil(Node *root, int index){
if (root==NULL) return ;
int preData=root->data;
if (index==-1)index=root->data;
else M[index][preData]=1;
MatrixUtil(root->left,preData);
MatrixUtil(root->right,preData);
}
void Matrix(Node *root){
MatrixUtil(root,-1);
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]);
}
}
printMatrix();
}
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
import java.util.*;
class GFG
{
static final int size = 6 ;
static int [][]M = new int [size][size];
static class Node
{
int data;
Node left, right;
};
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();
}
}
static void MatrixUtil(Node root, int index)
{
if (root == null ) return ;
int preData = root.data;
if (index == - 1 )index = root.data;
else M[index][preData] = 1 ;
MatrixUtil(root.left, preData);
MatrixUtil(root.right, preData);
}
static void Matrix(Node root)
{
MatrixUtil(root, - 1 );
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 ;
}
}
}
printMatrix();
}
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);
}
}
|
Python3
size = 6
M = [[ 0 for j in range (size)]
for i in range (size)]
class Node:
def __init__( self , data):
self .left = None
self .right = None
self .data = data
def 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 ()
def MatrixUtil(root, index):
if (root = = None ):
return
preData = root.data
if (index = = - 1 ):
index = root.data
else :
M[index][preData] = 1
MatrixUtil(root.left, preData)
MatrixUtil(root.right, preData)
def Matrix(root):
MatrixUtil(root, - 1 )
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]))
printMatrix()
if __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)
|
C#
using System;
class GFG
{
static readonly int size = 6;
static int [,]M = new int [size, size];
public
class Node
{
public
int data;
public
Node left, right;
};
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();
}
}
static void MatrixUtil(Node root, int index)
{
if (root == null )
return ;
int preData = root.data;
if (index == -1)index = root.data;
else M[index,preData] = 1;
MatrixUtil(root.left, preData);
MatrixUtil(root.right, preData);
}
static void Matrix(Node root)
{
MatrixUtil(root, -1);
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;
}
}
}
printMatrix();
}
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);
}
}
|
Javascript
<script>
var size = 6;
var M = Array(size).fill().map(()=>Array(size).fill(0));
class Node {
constructor(val) {
this .data = val;
this .left = null ;
this .right = null ;
}
}
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/>" );
}
}
function MatrixUtil(root , index) {
if (root == null )
return ;
var preData = root.data;
if (index == -1)
index = root.data;
else
M[index][preData] = 1;
MatrixUtil(root.left, preData);
MatrixUtil(root.right, preData);
}
function Matrix(root) {
MatrixUtil(root, -1);
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;
}
}
}
printMatrix();
}
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);
</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).
Auxiliary Space: O(n2)
How to do reverse – construct tree from ancestor matrix?
Construct tree from ancestor matrix
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...