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
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
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 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
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
Find root of n-ary tree from given list of nodes Given an N-ary tree as a list of nodes Node[] tree. Each node has a unique value, the task is to find the root of the tree. N-ary treeExamples: Input: 1 / | \ 2 3 4 \ 5 Output: Root value is 1 Input: 5 / | \ 3 6 7 / \ / \ 9 2 1 8 Output: Root value is 5 Naive approach: To solve the problem follow th
8 min read
Construct Binary Tree from given Parent Array representation | Iterative Approach 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
12 min read
Construct Special Binary Tree from given Inorder traversal Given Inorder Traversal of a Special Binary Tree in which the key of every node is greater than keys in left and right children, construct the Binary Tree and return root. Examples: Input: inorder[] = {5, 10, 40, 30, 28} Output: root of following tree 40 / \ 10 30 / \ 5 28 Input: inorder[] = {1, 5,
14 min read
Construct a Complete N-ary Tree from given Postorder Traversal Given an array arr[] of size M that contains the post-order traversal of a complete N-ary tree, the task is to generate the N-ary tree and print its preorder traversal. A complete tree is a tree where all the levels of the tree are completely filled, except may be for the last level but the nodes in
13 min read
Construct a complete binary tree from given array in level order fashion Given an array of elements, our task is to construct a complete binary tree from this array in a level order fashion. That is, elements from the left in the array will be filled in the tree level-wise starting from level 0.Examples: Input : arr[] = {1, 2, 3, 4, 5, 6}Output : Root of the following tr
11 min read