Given a 2D integer array where each row represents the relation between the nodes (relation[i] = [parenti, childi, isLefti]). The task is to construct the binary tree described by the 2D matrix and print the LevelOrder Traversal of the formed Binary Tree.
Examples:
Input: Relation[] = [[20, 15, 1], [20, 17, 0], [50, 20, 1], [50, 80, 0], [80, 19, 1]]
Output: [50, 20, 80, 15, 17, 19]
Explanation: The root node is the node with the value 50 since it has no parent.Input: Relation[] = [[1, 2, 1], [2, 3, 0], [3, 4, 1]]
Output: [1, 2, 3, 4]
Explanation: The root node is the node with the value 1 since it has no parent.
Approach: To solve the problem follow the below idea:
Iterate over the given 2D matrix(Relation Array) and see if the parent Node is present in the map or not.
Follow the Below steps to solve the above approach:
- Create a map data Structure that will store the address of each of the nodes formed with their values.
- Iterate over the given 2D matrix(Relation Array) and see if the parentNode is present in the map or not.
- If the parentNode is present in the map then there is no need of making a new node, Just store the address of the parentNode in a variable.
- If the parentNode is not present in the map then form a parentNode of the given value and store its address in the map. (Because this parentNode can be the childNode of some other Node).
- Similarly, Repeat Step 2 for child Node also i.e.,
- If the childNode is present in the map then there is no need of making a new node, Just store the address of the childNode in a variable.
- If the childNode is not present in the map then form a childNode of the given value and store its address in the map(Because this childNode can be the parentNode of some other Node).
- Form the relation between the parentNode and the childNode for each iteration depending on the value of the third value of the array of each iteration. i.e.,
- If the third value of the array in the given iteration is 1 then it means that the childNode is the left child of the parentNode formed for the given iteration.
- If the third value of the array in the given iteration is 0 then it means that the childNode is the left child of the parentNode formed for the given iteration.
- If carefully observed we know that the root node is the only node that has no Parent.
- Store all the values of the childNode that is present in the given 2D matrix (Relation Array) in a data structure (let’s assume a map data structure).
- Again iterate the 2D matrix (RelationArray) to check which parentNode value is not present in the map data structure formed in step 5).
- Print the level Order Traversal of the thus-formed tree.
Below is the implementation of the above approach.
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std;
// Binary Tree Node struct Node {
int data;
Node *left, *right;
}; // Returns new Node with data as input // to below function. Node* newNode( int d)
{ Node* temp = new Node;
temp->data = d;
temp->left = nullptr;
temp->right = nullptr;
return temp;
} // Function to create tree from // given description Node* createBinaryTree(vector<vector< int > >& descriptions)
{ unordered_map< int , Node*> mp;
for ( auto it : descriptions) {
Node *parentNode, *childNode;
// Check if the parent Node is
// already formed or not
if (mp.find(it[0]) != mp.end()) {
parentNode = mp[it[0]];
}
else {
parentNode = newNode(it[0]);
mp[it[0]] = parentNode;
}
// Check if the child Node is
// already formed or not
if (mp.find(it[1]) != mp.end()) {
childNode = mp[it[1]];
}
else {
childNode = newNode(it[1]);
mp[it[1]] = childNode;
}
// Making the Edge Between parent
// and child Node
if (it[2] == 1) {
parentNode->left = childNode;
}
else {
parentNode->right = childNode;
}
}
// Store the childNode
unordered_map< int , int > storeChild;
for ( auto it : descriptions) {
storeChild[it[1]] = 1;
}
// Find the root of the Tree
Node* root;
for ( auto it : descriptions) {
if (storeChild.find(it[0]) == storeChild.end()) {
root = mp[it[0]];
}
}
return root;
} // Level order Traversal void printLevelOrder(Node* root)
{ // Base Case
if (root == nullptr) {
return ;
}
// Create an empty queue for
// level order traversal
queue<Node*> q;
// Enqueue Root and initialize height
q.push(root);
while (q.empty() == false ) {
// Print front of queue and
// remove it from queue
Node* node = q.front();
cout << node->data << " " ;
q.pop();
// Enqueue left child
if (node->left != nullptr) {
q.push(node->left);
}
// Enqueue right child
if (node->right != nullptr) {
q.push(node->right);
}
}
} // Driver Code int main()
{ vector<vector< int > > RelationArray = { { 20, 15, 1 },
{ 20, 17, 0 },
{ 50, 20, 1 },
{ 50, 80, 0 },
{ 80, 19, 1 } };
Node* root = createBinaryTree(RelationArray);
printLevelOrder(root);
cout << endl;
vector<vector< int > > RelationArray2
= { { 1, 2, 1 }, { 2, 3, 0 }, { 3, 4, 1 } };
Node* root2 = createBinaryTree(RelationArray2);
printLevelOrder(root2);
return 0;
} |
// Java code for the above approach: import java.io.*;
import java.util.*;
// Binary Tree Node class Node {
int data;
Node left, right;
Node( int d)
{
data = d;
left = right = null ;
}
} class GFG {
// Returns new Node with data as input
// to below function.
static Node newNode( int d)
{
Node temp = new Node(d);
temp.left = null ;
temp.right = null ;
return temp;
}
// Function to create tree from
// given description
static Node
createBinaryTree(List<List<Integer> > descriptions)
{
Map<Integer, Node> mp = new HashMap<>();
for (List<Integer> it : descriptions) {
Node parentNode, childNode;
// Check if the parent Node is
// already formed or not
if (mp.containsKey(it.get( 0 ))) {
parentNode = mp.get(it.get( 0 ));
}
else {
parentNode = newNode(it.get( 0 ));
mp.put(it.get( 0 ), parentNode);
}
// Check if the child Node is
// already formed or not
if (mp.containsKey(it.get( 1 ))) {
childNode = mp.get(it.get( 1 ));
}
else {
childNode = newNode(it.get( 1 ));
mp.put(it.get( 1 ), childNode);
}
// Making the Edge Between parent
// and child Node
if (it.get( 2 ) == 1 ) {
parentNode.left = childNode;
}
else {
parentNode.right = childNode;
}
}
// Store the childNode
Map<Integer, Integer> storeChild = new HashMap<>();
for (List<Integer> it : descriptions) {
storeChild.put(it.get( 1 ), 1 );
}
// Find the root of the Tree
Node root = null ;
for (List<Integer> it : descriptions) {
if (!storeChild.containsKey(it.get( 0 ))) {
root = mp.get(it.get( 0 ));
}
}
return root;
}
// Level order Traversal
static void printLevelOrder(Node root)
{
// Base Case
if (root == null ) {
return ;
}
// Create an empty queue for
// level order traversal
Queue<Node> q = new LinkedList<>();
// Enqueue Root and initialize height
q.add(root);
while (!q.isEmpty()) {
// Print front of queue and
// remove it from queue
Node node = q.peek();
System.out.print(node.data + " " );
q.poll();
// Enqueue left child
if (node.left != null ) {
q.add(node.left);
}
// Enqueue right child
if (node.right != null ) {
q.add(node.right);
}
}
}
public static void main(String[] args)
{
List<List<Integer> > RelationArray
= Arrays.asList(Arrays.asList( 20 , 15 , 1 ),
Arrays.asList( 20 , 17 , 0 ),
Arrays.asList( 50 , 20 , 1 ),
Arrays.asList( 50 , 80 , 0 ),
Arrays.asList( 80 , 19 , 1 ));
Node root = createBinaryTree(RelationArray);
printLevelOrder(root);
System.out.println();
List<List<Integer> > RelationArray2 = Arrays.asList(
Arrays.asList( 1 , 2 , 1 ), Arrays.asList( 2 , 3 , 0 ),
Arrays.asList( 3 , 4 , 1 ));
Node root2 = createBinaryTree(RelationArray2);
printLevelOrder(root2);
}
} // This code is contributed by lokeshmvs21. |
# Python code for the above approach from typing import List
# Binary Tree Node class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
# Returns new Node with data as input # to below function. def newNode(d):
temp = Node(d)
return temp
# Function to create tree from # given description def createBinaryTree(descriptions: List [ List [ int ]]) - > Node:
mp = {}
for it in descriptions:
parentNode, childNode = None , None
# Check if the parent Node is
# already formed or not
if it[ 0 ] in mp:
parentNode = mp[it[ 0 ]]
else :
parentNode = newNode(it[ 0 ])
mp[it[ 0 ]] = parentNode
# Check if the child Node is
# already formed or not
if it[ 1 ] in mp:
childNode = mp[it[ 1 ]]
else :
childNode = newNode(it[ 1 ])
mp[it[ 1 ]] = childNode
# Making the Edge Between parent
# and child Node
if it[ 2 ] = = 1 :
parentNode.left = childNode
else :
parentNode.right = childNode
# Store the childNode
storeChild = {}
for it in descriptions:
storeChild[it[ 1 ]] = 1
# Find the root of the Tree
root = None
for it in descriptions:
if it[ 0 ] not in storeChild:
root = mp[it[ 0 ]]
return root
# Level order Traversal def printLevelOrder(root: Node):
# Base Case
if root is None :
return
# Create an empty queue for
# level order traversal
q = []
# Enqueue Root and initialize height
q.append(root)
while len (q) > 0 :
# Print front of queue and
# remove it from queue
node = q.pop( 0 )
print (node.data, end = ' ' )
# Enqueue left child
if node.left is not None :
q.append(node.left)
# Enqueue right child
if node.right is not None :
q.append(node.right)
# Driver Code if __name__ = = "__main__" :
relationArray = [[ 20 , 15 , 1 ], [ 20 , 17 , 0 ], [ 50 , 20 , 1 ], [ 50 , 80 , 0 ], [ 80 , 19 , 1 ]]
root = createBinaryTree(relationArray)
printLevelOrder(root)
print ()
relationArray2 = [[ 1 , 2 , 1 ], [ 2 , 3 , 0 ], [ 3 , 4 , 1 ]]
root2 = createBinaryTree(relationArray2)
printLevelOrder(root2)
# This code is contributed by Potta Lokesh |
// C# code for the above approach: using System;
using System.Collections.Generic;
using System.Linq;
// Binary Tree Node class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
this .left = null ;
this .right = null ;
}
} public class GFG {
// Returns new Node with data as input
// to below function.
static Node NewNode( int data)
{
Node temp = new Node(data);
temp.left = null ;
temp.right = null ;
return temp;
}
// Function to create tree from
// given description
static Node
CreateBinaryTree(List<List< int > > descriptions)
{
Dictionary< int , Node> mp
= new Dictionary< int , Node>();
foreach (List< int > it in descriptions)
{
Node parentNode, childNode;
// Check if the parent Node is
// already formed or not
if (mp.ContainsKey(it[0])) {
parentNode = mp[it[0]];
}
else {
parentNode = NewNode(it[0]);
mp[it[0]] = parentNode;
}
// Check if the child Node is
// already formed or not
if (mp.ContainsKey(it[1])) {
childNode = mp[it[1]];
}
else {
childNode = NewNode(it[1]);
mp[it[1]] = childNode;
}
// Making the Edge Between parent
// and child Node
if (it[2] == 1) {
parentNode.left = childNode;
}
else {
parentNode.right = childNode;
}
}
// Store the childNode
Dictionary< int , int > storeChild
= new Dictionary< int , int >();
foreach (List< int > it in descriptions)
{
storeChild[it[1]] = 1;
}
// Find the root of the Tree
Node root = null ;
foreach (List< int > it in descriptions)
{
if (!storeChild.ContainsKey(it[0])) {
root = mp[it[0]];
}
}
return root;
}
// Level order Traversal
static void PrintLevelOrder(Node root)
{
// Base Case
if (root == null ) {
return ;
}
// Create an empty queue for
// level order traversal
Queue<Node> q = new Queue<Node>();
// Enqueue Root and initialize height
q.Enqueue(root);
while (q.Count > 0) {
// Print front of queue and
// remove it from queue
Node node = q.Peek();
Console.Write(node.data + " " );
q.Dequeue();
// Enqueue left child
if (node.left != null ) {
q.Enqueue(node.left);
}
// Enqueue right child
if (node.right != null ) {
q.Enqueue(node.right);
}
}
}
static public void Main()
{
List<List< int > > RelationArray
= new List<List< int > >{
new List< int >{ 20, 15, 1 },
new List< int >{ 20, 17, 0 },
new List< int >{ 50, 20, 1 },
new List< int >{ 50, 80, 0 },
new List< int >{ 80, 19, 1 }
};
Node root = CreateBinaryTree(RelationArray);
PrintLevelOrder(root);
Console.WriteLine();
List<List< int > > RelationArray2
= new List<List< int > >{
new List< int >{ 1, 2, 1 },
new List< int >{ 2, 3, 0 },
new List< int >{ 3, 4, 1 }
};
Node root2 = CreateBinaryTree(RelationArray2);
PrintLevelOrder(root2);
}
} // This code is contributed by lokesh. |
// JavaScript Code for the above approach // Node Class class Node { constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
} // Function to create tree from given description function createBinaryTree(descriptions) {
let mp = new Map();
for (let it of descriptions) {
let parentNode, childNode;
// Check if the parent Node is
// already formed or not
if (mp.has(it[0])) {
parentNode = mp.get(it[0]);
}
else {
parentNode = new Node(it[0]);
mp.set(it[0], parentNode);
}
// Check if the child Node is
// already formed or not
if (mp.has(it[1])) {
childNode = mp.get(it[1]);
}
else {
childNode = new Node(it[1]);
mp.set(it[1], childNode);
}
// Making the Edge Between parent
// and child Node
if (it[2] == 1) {
parentNode.left = childNode;
}
else {
parentNode.right = childNode;
}
}
// Store the childNode
let storeChild = new Map();
for (let it of descriptions) {
storeChild.set(it[1], 1);
}
// Find the root of the Tree
let root;
for (let it of descriptions) {
if (!storeChild.has(it[0])) {
root = mp.get(it[0]);
}
}
return root;
} // Level order Traversal function printLevelOrder(root) {
// Base Case
if (root == null ) {
return ;
}
// Create an empty queue for
// level order traversal
let q = [];
// Enqueue Root and initialize height
q.push(root);
while (q.length > 0) {
// Print front of queue and
// remove it from queue
let node = q.shift();
console.log(node.data + " " );
// Enqueue left child
if (node.left != null ) {
q.push(node.left);
}
// Enqueue right child
if (node.right != null ) {
q.push(node.right);
}
}
} // Driver Code let RelationArray = [ [20, 15, 1],
[20, 17, 0],
[50, 20, 1],
[50, 80, 0],
[80, 19, 1],
]; let root = createBinaryTree(RelationArray); printLevelOrder(root); let RelationArray2 = [ [1, 2, 1],
[2, 3, 0],
[3, 4, 1],
]; let root2 = createBinaryTree(RelationArray2); printLevelOrder(root2); // This code is contributed by adityamaharshi21 |
50 20 80 15 17 19 1 2 3 4
Time Complexity: O(N) where N is the number of rows present in the 2D matrix + O(M) where M is the number of nodes present in the Tree (for Level Order Traversal)
Auxiliary Space: O(M) where M is the number of nodes present in the Tree (We are storing the values of the nodes along with their address in the map).
Related Articles: