Create Binary Tree from given Array of relation between nodes
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 |
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:
Please Login to comment...