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:
Similar Reads
Queries to find distance between two nodes of a Binary tree
Given a binary tree, the task is to find the distance between two keys in a binary tree, no parent pointers are given. The distance between two nodes is the minimum number of edges to be traversed to reach one node from other. We have already discussed a method which uses segment tree to reduce the
15+ min read
Construct Binary Tree from given Parent Array representation
Given an array that represents a tree in such a way that array indexes are values in tree nodes and array values give the parent node of that particular index (or node). The value of the root node index would always be -1 as there is no parent for root. Construct the standard linked representation o
15+ min read
Shortest path between two nodes in array like representation of binary tree
Consider a binary tree in which each node has two children except the leaf nodes. If a node is labeled as 'v' then its right children will be labeled as 2v+1 and left children as 2v. Root is labelled asGiven two nodes labeled as i and j, the task is to find the shortest distance and the path from i
12 min read
Print path between any two nodes in a Binary Tree
Given a Binary Tree of distinct nodes and a pair of nodes. The task is to find and print the path between the two given nodes in the binary tree. For Example, in the above binary tree the path between the nodes 7 and 4 is 7 -> 3 -> 1 -> 4. The idea is to find paths from root nodes to the tw
12 min read
Create a binary tree from post order traversal and leaf node array
Given 2 arrays, the first one containing postorder traversal sequence and the second one containing the information whether the corresponding node in the first array is a leaf node or a non-leaf node, create a binary tree and return its root and print it's inorder traversal. (There can be more than
6 min read
Print cousins of a given node in Binary Tree
Given a binary tree and a node, print all cousins of given node. Note that siblings should not be printed.Example: Input : root of below tree 1 / \ 2 3 / \ / \ 4 5 6 7 and pointer to a node say 5. Output : 6, 7 The idea to first find level of given node using the approach discussed here. Once we hav
15+ min read
Print the Forests of a Binary Tree after removal of given Nodes
Given a Binary Tree and an array arr[] consisting of values of nodes to be deleted, the task is to print Inorder Traversal of the forests after deleting the nodes. Examples: Input: arr[] = {10, 5} 10 / \ 20 30 / \ \ 4 5 7 Output: 4 20 30 7Input: arr[] = {5} 1 / \ 5 6 / \ 10 12 Output: 10 1 6 12 Appr
8 min read
Print Ancestors of a given node in Binary Tree
Given a Binary Tree and a key, write a function that prints all the ancestors of the key in the given binary tree. For example, if the given tree is following Binary Tree and the key is 7, then your function should print 4, 2, and 1. 1 / \ 2 3 / \ 4 5 / 7Recommended PracticeAncestors in Binary TreeT
13 min read
Queries to find distance between two nodes of a Binary tree - O(logn) method
Given a binary tree, the task is to find the distance between two keys in a binary tree, no parent pointers are given. Distance between two nodes is the minimum number of edges to be traversed to reach one node from other. This problem has been already discussed in previous post but it uses three tr
15+ min read
Construct Ancestor Matrix from a Given Binary Tree
Given a Binary Tree where all values are from 0 to n-1. Construct an ancestor matrix mat[n][n] where the ancestor matrix is defined as below. mat[i][j] = 1 if i is ancestor of jmat[i][j] = 0, otherwiseExamples: Input: Output: {{0 1 1} {0 0 0} {0 0 0}}Input: Output: {{0 0 0 0 0 0} {1 0 0 0 1 0} {0 0
15+ min read