Given an ancestor matrix mat[n][n] where Ancestor matrix is defined as below.
mat[i][j] = 1 if i is ancestor of j mat[i][j] = 0, otherwise
Construct a Binary Tree from a given ancestor matrix where all its values of nodes are from 0 to n-1.
- It may be assumed that the input provided in the program is valid and the tree can be constructed out of it.
- Many Binary trees can be constructed from one input. The program will construct any one of them.
Examples:
Input: 0 1 1 0 0 0 0 0 0 Output: Root of one of the below trees. 0 0 / \ OR / \ 1 2 2 1 Input: 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 Output: Root of one of the below trees. 5 5 5 / \ / \ / \ 1 2 OR 2 1 OR 1 2 OR .... / \ / / / \ / \ / 0 4 3 3 0 4 4 0 3 There are different possible outputs because ancestor matrix doesn't store that which child is left and which is right.
We strongly recommend you to minimize your browser and try this yourself first.
Observations used in the solution:
- The rows that correspond to leaves have all 0’s
- The row that corresponds to root has maximum number of 1’s.
- Count of 1’s in i’th row indicates number of descendants of node i.
The idea is to construct the tree in bottom up manner.
- Create an array of node pointers node[].
- Store row numbers that correspond to a given count. We have used multimap for this purpose.
- Process all entries of multimap from smallest count to largest (Note that entries in map and multimap can be traversed in sorted order). Do following for every entry.
- Create a new node for current row number.
- If this node is not a leaf node, consider all those descendants of it whose parent is not set, make current node as its parent.
- The last processed node (node with maximum sum) is root of tree.
Below is the implementation of the above approach:
// Given an ancestor matrix for binary tree, construct // the tree. #include <bits/stdc++.h> using namespace std;
# define N 6 /* 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);
} // Constructs tree from ancestor matrix Node* ancestorTree( int mat[][N])
{ // Binary array to determine whether
// parent is set for node i or not
int parent[N] = {0};
// Root will store the root of the constructed tree
Node* root = NULL;
// Create a multimap, sum is used as key and row
// numbers are used as values
multimap< int , int > mm;
for ( int i = 0; i < N; i++)
{
int sum = 0; // Initialize sum of this row
for ( int j = 0; j < N; j++)
sum += mat[i][j];
// insert(sum, i) pairs into the multimap
mm.insert(pair< int , int >(sum, i));
}
// node[i] will store node for i in constructed tree
Node* node[N];
// Traverse all entries of multimap. Note that values
// are accessed in increasing order of sum
for ( auto it = mm.begin(); it != mm.end(); ++it)
{
// create a new node for every value
node[it->second] = newNode(it->second);
// To store last processed node. This node will be
// root after loop terminates
root = node[it->second];
// if non-leaf node
if (it->first != 0)
{
// traverse row 'it->second' in the matrix
for ( int i = 0; i < N; i++)
{
// if parent is not set and ancestor exits
if (!parent[i] && mat[it->second][i])
{
// check for unoccupied left/right node
// and set parent of node i
if (!node[it->second]->left)
node[it->second]->left = node[i];
else
node[it->second]->right = node[i];
parent[i] = 1;
}
}
}
}
return root;
} /* Given a binary tree, print its nodes in inorder */ void printInorder(Node* node)
{ if (node == NULL)
return ;
printInorder(node->left);
printf ( "%d " , node->data);
printInorder(node->right);
} // Driver code int main()
{ int mat[N][N] = {{ 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 }
};
Node* root = ancestorTree(mat);
cout << "Inorder traversal of tree is \n" ;
// Function call
printInorder(root);
return 0;
} |
// Given an ancestor matrix for binary tree, construct // the tree. import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
/* A binary tree node */ class Node {
int data;
Node left, right;
Node( int d)
{
data = d;
left = right = null ;
}
} public class TreeFromAncestorMatrix {
static Node ancestorNode( int [][] mat)
{
int n = mat.length;
// Binary array to determine whether parent is set
// for node i or not
int [] parent = new int [n];
Node root = null ;
// Map to store row numbers as key and
// their sum as their values
Map<Integer, Integer> map = new HashMap<>();
for ( int i = 0 ; i < n; i++) {
int sum = 0 ;
for ( int j = 0 ; j < n; j++)
sum += mat[i][j];
map.put(i, sum);
}
// node[i] will store node for i in
//constructed tree
Node node[] = new Node[n];
// Sorting the map according to its
//values
Map<Integer, Integer> sorted
= map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(
e
-> e.getKey(),
e
-> e.getValue(),
(e1, e2) -> e2, LinkedHashMap:: new ));
// Traverse all entries of sorted Map.
// Note that values are accessed in increasing order
// of sum
for (Map.Entry<Integer, Integer> entry :
sorted.entrySet()) {
int key = entry.getKey();
int value = entry.getValue();
// create a new node for every
// value
node[key] = new Node(key);
// if it is an internal node
if (value != 0 ) {
// Traverse row
//corresponding to the node
for ( int i = 0 ; i < n; i++)
{
// if parent is not set and
//ancestor exits
if (parent[i] == 0
&& mat[key][i] != 0 )
{
// check for unoccupied
// left/right node and
//set parent of node i
if (node[key].left == null )
node[key].left = node[i];
else
node[key].right = node[i];
parent[i] = 1 ;
}
// To store last processed
// node. This node will be root after
// loop terminates
root = node[key];
}
}
}
return root;
}
/* Given a binary tree, print its nodes in inorder */
static void inOrder(Node root)
{
if (root == null )
return ;
inOrder(root.left);
System.out.print(root.data + " " );
inOrder(root.right);
}
// Driver code
public static void main(String[] args)
{
int mat[][] = {
{ 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 }
};
Node root = ancestorNode(mat);
// Function call
inOrder(root);
}
} // contribute by amarsomani |
# key structure to store a binary tree node class Node:
def __init__( self , key, left = None , right = None ):
self .key = key
self .left = left
self .right = right
# Utility function to print binary tree nodes in-order fashion def inorder(node):
if node:
inorder(node.left)
print (node.key, end = ' ' )
inorder(node.right)
# Function to construct a binary tree # from specified ancestor matrix def constructBT(mat):
# get number of rows in the matrix
N = len (mat)
# create an empty multi-dict
dict = {}
# Use sum as key and row numbers as values in the multi-dict
for i in range (N):
# find the sum of the current row
total = sum (mat[i])
# insert the sum and row number into the dict
dict .setdefault(total, []).append(i)
# node[i] will store node for i in constructed tree
node = [Node( - 1 )] * N
last = 0
# the value of parent[i] is true if parent is set for i'th node
parent = [ False ] * N
# Traverse the dictionary in sorted order (default behavior)
for key in dict .keys():
for row in dict .get(key):
last = row
# create a new node
node[row] = Node(row)
# if leaf node, do nothing
if key = = 0 :
continue
# traverse row
for i in range (N):
# do if parent is not set and ancestor exits
if not parent[i] and mat[row][i] = = 1 :
# check for the unoccupied node
if node[row].left is None :
node[row].left = node[i]
else :
node[row].right = node[i]
# set parent for i'th node
parent[i] = True
# last processed node is the root
return node[last]
# Construct a Binary Tree from Ancestor Matrix if __name__ = = '__main__' :
mat = [[ 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 , 0 , 0 ]]
root = constructBT(mat)
inorder(root)
# This code is contributed by Priyadarshini Kumari |
// Given an ancestor matrix for binary tree, construct // the tree. using System;
using System.Collections.Generic;
using System.Linq;
/* A binary tree node */ public class Node
{
public
int data;
public
Node left, right;
public
Node( int d)
{
data = d;
left = right = null ;
}
}
public class TreeFromAncestorMatrix
{ static Node ancestorNode( int [,] mat)
{
int n = mat.GetLength(0);
// Binary array to determine whether parent is set
// for node i or not
int [] parent = new int [n];
Node root = null ;
// Map to store row numbers as key and
// their sum as their values
Dictionary< int , int > map = new Dictionary< int , int >();
for ( int i = 0; i < n; i++)
{
int sum = 0;
for ( int j = 0; j < n; j++)
sum += mat[i, j];
map.Add(i, sum);
}
// node[i] will store node for i in
//constructed tree
Node []node = new Node[n];
var sorted = from entry in map orderby entry.Value ascending select entry;
// Traverse all entries of sorted Map.
// Note that values are accessed in increasing order
// of sum
foreach (KeyValuePair< int , int > entry in
sorted)
{
int key = entry.Key;
int value = entry.Value;
// create a new node for every
// value
node[key] = new Node(key);
// if it is an internal node
if (value != 0)
{
// Traverse row
//corresponding to the node
for ( int i = 0; i < n; i++)
{
// if parent is not set and
//ancestor exits
if (parent[i] == 0
&& mat[key,i] != 0)
{
// check for unoccupied
// left/right node and
//set parent of node i
if (node[key].left == null )
node[key].left = node[i];
else
node[key].right = node[i];
parent[i] = 1;
}
// To store last processed
// node. This node will be root after
// loop terminates
root = node[key];
}
}
}
return root;
}
/* Given a binary tree, print its nodes in inorder */
static void inOrder(Node root)
{
if (root == null )
return ;
inOrder(root.left);
Console.Write(root.data + " " );
inOrder(root.right);
}
// Driver code
public static void Main(String[] args)
{
int [,]mat = {
{ 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 }
};
Node root = ancestorNode(mat);
// Function call
inOrder(root);
}
} // This code is contributed by Rajput-Ji |
<script> // Given an ancestor matrix for binary tree, construct // the tree. /* A binary tree node */ class Node { constructor(d)
{
this .data = d;
this .left = null ;
this .right = null ;
}
} function ancestorNode( mat)
{ var n = mat.length;
// Binary array to determine whether parent is set
// for node i or not
var parent = Array(n).fill(0);
var root = null ;
// Map to store row numbers as key and
// their sum as their values
var map = new Map();
for ( var i = 0; i < n; i++)
{
var sum = 0;
for ( var j = 0; j < n; j++)
sum += mat[i][j];
map.set(i, sum);
}
// node[i] will store node for i in
//constructed tree
var node = Array(n).fill( null );
// Traverse all entries of sorted Map.
// Note that values are accessed in increasing order
// of sum
for ( var data of [...map].sort((a,b)=> a[1]-b[1]))
{
var key = data[0];
var value = data[1];
// create a new node for every
// value
node[key] = new Node(key);
// if it is an internal node
if (value != 0)
{
// Traverse row
//corresponding to the node
for ( var i = 0; i < n; i++)
{
// if parent is not set and
//ancestor exits
if (parent[i] == 0
&& mat[key][i] != 0)
{
// check for unoccupied
// left/right node and
//set parent of node i
if (node[key].left == null )
node[key].left = node[i];
else
node[key].right = node[i];
parent[i] = 1;
}
// To store last processed
// node. This node will be root after
// loop terminates
root = node[key];
}
}
};
return root;
} /* Given a binary tree, print its nodes in inorder */ function inOrder(root)
{ if (root == null )
return ;
inOrder(root.left);
document.write(root.data + " " );
inOrder(root.right);
} // Driver code var mat = [
[ 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 ]
]; var root = ancestorNode(mat);
// Function call inOrder(root); // This code is contributed by rdtank. </script> |
0 1 4 5 3 2
Time Complexity: O(N2), where N is the number of nodes in the tree.
Space Complexity: O(N2), where N is the number of nodes in the tree.
Note that we can also use an array of vectors in place of multimap. We have used multimap for simplicity. Array of vectors would improve performance as inserting and accessing elements would take O(1) time.