Create Binary Tree from given Array of relation between nodes
Last Updated :
29 Dec, 2022
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.
Example1
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.
Example 2
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++
// 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
// 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.
Python3
# 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#
// 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
// 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
Output50 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: