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 of given Binary Tree from this given representation.
Examples:
Input: parent[] = {1, 5, 5, 2, 2, -1, 3}
Output: root of below tree
5
/ \
1 2
/ / \
0 3 4
/
6
Explanation:
Index of -1 is 5. So 5 is root.
5 is present at indexes 1 and 2. So 1 and 2 are
children of 5.
1 is present at index 0, so 0 is child of 1.
2 is present at indexes 3 and 4. So 3 and 4 are
children of 2.
3 is present at index 6, so 6 is child of 3.
Input: parent[] = {-1, 0, 0, 1, 1, 3, 5};
Output: root of below tree
0
/ \
1 2
/ \
3 4
/
5
/
6
Expected time complexity is O(n) where n is number of elements in given array.
We strongly recommend to minimize your browser and try this yourself first.
A Simple Solution to recursively construct by first searching the current root, then recurring for the found indexes (there can be at most two indexes) and making them left and right subtrees of root. This solution takes O(n2) as we have to linearly search for every node.
An Efficient Solution can solve the above problem in O(n) time. The idea is to use extra space. An array created[0..n-1] is used to keep track of created nodes.
createTree(parent[], n)
- Create an array of pointers say created[0..n-1]. The value of created[i] is NULL if node for index i is not created, else value is pointer to the created node.
- Do following for every index i of given array
createNode(parent, i, created)
createNode(parent[], i, created[])
- If created[i] is not NULL, then node is already created. So return.
- Create a new node with value ‘i’.
- If parent[i] is -1 (i is root), make created node as root and return.
- Check if parent of ‘i’ is created (We can check this by checking if created[parent[i]] is NULL or not.
- If parent is not created, recur for parent and create the parent first.
- Let the pointer to parent be p. If p->left is NULL, then make the new node as left child. Else make the new node as right child of parent.
Following is C++ implementation of above idea.
C++14
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int key;
struct Node *left, *right;
};
Node *newNode( int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
void createNode( int parent[], int i, Node *created[], Node **root)
{
if (created[i] != NULL)
return ;
created[i] = newNode(i);
if (parent[i] == -1)
{
*root = created[i];
return ;
}
if (created[parent[i]] == NULL)
createNode(parent, parent[i], created, root);
Node *p = created[parent[i]];
if (p->left == NULL)
p->left = created[i];
else
p->right = created[i];
}
Node *createTree( int parent[], int n)
{
Node *created[n];
for ( int i=0; i<n; i++)
created[i] = NULL;
Node *root = NULL;
for ( int i=0; i<n; i++)
createNode(parent, i, created, &root);
return root;
}
inline void newLine(){
cout << "\n" ;
}
void inorder(Node *root)
{
if (root != NULL)
{
inorder(root->left);
cout << root->key << " " ;
inorder(root->right);
}
}
int main()
{
int parent[] = {-1, 0, 0, 1, 1, 3, 5};
int n = sizeof parent / sizeof parent[0];
Node *root = createTree(parent, n);
cout << "Inorder Traversal of constructed tree\n" ;
inorder(root);
newLine();
}
|
Java
class Node
{
int key;
Node left, right;
public Node( int key)
{
this .key = key;
left = right = null ;
}
}
class BinaryTree
{
Node root;
void createNode( int parent[], int i, Node created[])
{
if (created[i] != null )
return ;
created[i] = new Node(i);
if (parent[i] == - 1 )
{
root = created[i];
return ;
}
if (created[parent[i]] == null )
createNode(parent, parent[i], created);
Node p = created[parent[i]];
if (p.left == null )
p.left = created[i];
else
p.right = created[i];
}
Node createTree( int parent[], int n)
{
Node[] created = new Node[n];
for ( int i = 0 ; i < n; i++)
created[i] = null ;
for ( int i = 0 ; i < n; i++)
createNode(parent, i, created);
return root;
}
void newLine()
{
System.out.println( "" );
}
void inorder(Node node)
{
if (node != null )
{
inorder(node.left);
System.out.print(node.key + " " );
inorder(node.right);
}
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
int parent[] = new int []{- 1 , 0 , 0 , 1 , 1 , 3 , 5 };
int n = parent.length;
Node node = tree.createTree(parent, n);
System.out.println( "Inorder traversal of constructed tree " );
tree.inorder(node);
tree.newLine();
}
}
|
Python3
class Node:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
def createNode(parent, i, created, root):
if created[i] is not None :
return
created[i] = Node(i)
if parent[i] = = - 1 :
root[ 0 ] = created[i]
return
if created[parent[i]] is None :
createNode(parent, parent[i], created, root )
p = created[parent[i]]
if p.left is None :
p.left = created[i]
else :
p.right = created[i]
def createTree(parent):
n = len (parent)
created = [ None for i in range (n + 1 )]
root = [ None ]
for i in range (n):
createNode(parent, i, created, root)
return root[ 0 ]
def inorder(root):
if root is not None :
inorder(root.left)
print (root.key,end = " " )
inorder(root.right)
parent = [ - 1 , 0 , 0 , 1 , 1 , 3 , 5 ]
root = createTree(parent)
print ( "Inorder Traversal of constructed tree" )
inorder(root)
|
C#
using System;
public class Node
{
public int key;
public Node left, right;
public Node( int key)
{
this .key = key;
left = right = null ;
}
}
class GFG
{
public Node root;
public virtual void createNode( int [] parent,
int i, Node[] created)
{
if (created[i] != null )
{
return ;
}
created[i] = new Node(i);
if (parent[i] == -1)
{
root = created[i];
return ;
}
if (created[parent[i]] == null )
{
createNode(parent, parent[i], created);
}
Node p = created[parent[i]];
if (p.left == null )
{
p.left = created[i];
}
else
{
p.right = created[i];
}
}
public virtual Node createTree( int [] parent, int n)
{
Node[] created = new Node[n];
for ( int i = 0; i < n; i++)
{
created[i] = null ;
}
for ( int i = 0; i < n; i++)
{
createNode(parent, i, created);
}
return root;
}
public virtual void newLine()
{
Console.WriteLine( "" );
}
public virtual void inorder(Node node)
{
if (node != null )
{
inorder(node.left);
Console.Write(node.key + " " );
inorder(node.right);
}
}
public static void Main( string [] args)
{
GFG tree = new GFG();
int [] parent = new int []{-1, 0, 0, 1, 1, 3, 5};
int n = parent.Length;
Node node = tree.createTree(parent, n);
Console.WriteLine( "Inorder traversal of " +
"constructed tree " );
tree.inorder(node);
tree.newLine();
}
}
|
Javascript
<script>
class Node
{
constructor(key)
{
this .key = key;
this .left = null ;
this .right = null ;
}
}
var root = null ;
function createNode(parent, i, created)
{
if (created[i] != null )
{
return ;
}
created[i] = new Node(i);
if (parent[i] == -1)
{
root = created[i];
return ;
}
if (created[parent[i]] == null )
{
createNode(parent, parent[i], created);
}
var p = created[parent[i]];
if (p.left == null )
{
p.left = created[i];
}
else
{
p.right = created[i];
}
}
function createTree(parent, n)
{
var created = Array(n);
for ( var i = 0; i < n; i++)
{
created[i] = null ;
}
for ( var i = 0; i < n; i++)
{
createNode(parent, i, created);
}
return root;
}
function newLine()
{
document.write( "" );
}
function inorder(node)
{
if (node != null )
{
inorder(node.left);
document.write(node.key + " " );
inorder(node.right);
}
}
var parent = [-1, 0, 0, 1, 1, 3, 5];
var n = parent.length;
var node = createTree(parent, n);
document.write( "Inorder traversal of " +
"constructed tree<br>" );
inorder(node);
newLine();
</script>
|
Output
Inorder Traversal of constructed tree
6 5 3 1 4 0 2
Time Complexity: O(n^2)
In this approach, we iterate over the parent array, and in the worst case, we need to create a node for every element in the array. And in the createNode() function, the main time complexity is due to the recursive calls that depend on the height of the tree, which can be n. So, the overall time complexity of the algorithm is O(n^2).
Space Complexity: O(n)
The space complexity of the algorithm is linear, i.e., O(n), since we need to create a node for every element of the parent array.
Another Efficient Solution:
The idea is to first create all n new tree nodes, each having values from 0 to n – 1, where n is the size of parent array, and store them in any data structure like map, array etc to keep track of which node is created for which value. Then traverse the given parent array and build the tree by setting the parent-child relationship.
Algorithm
- Start with creating an array to store the reference of all newly created nodes corresponding to node value.
- Create n new tree nodes, each having a value from 0 to n-1, and store them in the reference array.
- Traverse the parent array and build the tree:
a. If the parent is -1, set the root to the current node having the value i which is stored in the reference array at index i.
b. If the parent’s left child is NULL, then map the left child to its parent.
c. Else, map the right child to its parent.
- Return the root of the newly constructed tree.
- End.
Following is the C++ implementation of the above idea.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* left = NULL;
struct Node* right = NULL;
Node() {}
Node( int x) { data = x; }
};
Node* createTree( int parent[], int n)
{
vector<Node*> ref;
Node* root = new Node();
for ( int i = 0; i < n; i++) {
Node* temp = new Node(i);
ref.push_back(temp);
}
for ( int i = 0; i < n; i++) {
if (parent[i] == -1) {
root = ref[i];
}
else {
if (ref[parent[i]]->left == NULL)
ref[parent[i]]->left = ref[i];
else
ref[parent[i]]->right = ref[i];
}
}
return root;
}
void inorder(Node* root)
{
if (root != NULL) {
inorder(root->left);
cout << root->data << " " ;
inorder(root->right);
}
}
int main()
{
int parent[] = { -1, 0, 0, 1, 1, 3, 5 };
int n = sizeof parent / sizeof parent[0];
Node* root = createTree(parent, n);
cout << "Inorder Traversal of constructed tree\n" ;
inorder(root);
return 0;
}
|
Java
class Node {
int key;
Node left, right;
public Node() {}
public Node( int key)
{
this .key = key;
left = right = null ;
}
}
class BinaryTree {
Node root;
Node createTree( int parent[], int n)
{
Node[] ref = new Node[n];
Node root = new Node();
for ( int i = 0 ; i < n; i++) {
Node temp = new Node(i);
ref[i] = temp;
}
for ( int i = 0 ; i < n; i++) {
if (parent[i] == - 1 ) {
root = ref[i];
}
else {
if (ref[parent[i]].left == null )
ref[parent[i]].left = ref[i];
else
ref[parent[i]].right = ref[i];
}
}
return root;
}
void inorder(Node node)
{
if (node != null ) {
inorder(node.left);
System.out.print(node.key + " " );
inorder(node.right);
}
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
int parent[] = new int [] { - 1 , 0 , 0 , 1 , 1 , 3 , 5 };
int n = parent.length;
Node node = tree.createTree(parent, n);
System.out.println(
"Inorder traversal of constructed tree " );
tree.inorder(node);
}
}
|
Python3
class Node:
def __init__( self , x):
self .data = x
self .left = None
self .right = None
def createTree(parent, n):
ref = []
for i in range ( 0 , n):
temp = Node(i)
ref.append(temp)
for i in range ( 0 , n):
if parent[i] = = - 1 :
root = ref[i]
else :
if ref[parent[i]].left is None :
ref[parent[i]].left = ref[i]
else :
ref[parent[i]].right = ref[i]
return root
def inorder(root):
if root is not None :
inorder(root.left)
print (root.data, end = " " )
inorder(root.right)
parent = [ - 1 , 0 , 0 , 1 , 1 , 3 , 5 ]
n = 7
root = createTree(parent, n)
print ( "Inorder traversal of constructed tree" )
inorder(root)
|
C#
using System;
class Node {
public int key;
public Node left, right;
public Node() {}
public Node( int key)
{
this .key = key;
left = right = null ;
}
}
class BinaryTree {
public Node root;
public Node createTree( int [] parent, int n)
{
Node[] refi = new Node[n];
Node root = new Node();
for ( int i = 0; i < n; i++) {
Node temp = new Node(i);
refi[i] = temp;
}
for ( int i = 0; i < n; i++) {
if (parent[i] == -1) {
root = refi[i];
}
else {
if (refi[parent[i]].left == null )
refi[parent[i]].left = refi[i];
else
refi[parent[i]].right = refi[i];
}
}
return root;
}
public void inorder(Node node)
{
if (node != null ) {
inorder(node.left);
Console.Write(node.key + " " );
inorder(node.right);
}
}
public static void Main(String[] args)
{
BinaryTree tree = new BinaryTree();
int [] parent = new int [] { -1, 0, 0, 1, 1, 3, 5 };
int n = parent.Length;
Node node = tree.createTree(parent, n);
Console.WriteLine(
"Inorder traversal of constructed tree " );
tree.inorder(node);
}
}
|
Javascript
class Node{
constructor(x){
this .data = x;
this .left = null ;
this .right = null ;
}
}
function createTree(parent, n){
let ref = [];
let root = new Node();
for (let i = 0; i<n; i++){
let temp = new Node(i);
ref.push(temp);
}
for (let i = 0; i<n; i++){
if (parent[i] == -1){
root = ref[i];
} else {
if (ref[parent[i]].left == null ){
ref[parent[i]].left = ref[i];
} else {
ref[parent[i]].right = ref[i];
}
}
}
return root;
}
function inorder(root){
if (root != null ){
inorder(root.left);
console.log(root.data + " " );
inorder(root.right);
}
}
let parent = [-1, 0, 0, 1, 1, 3, 5];
let n = parent.length;
let root = createTree(parent, n);
console.log( "Inorder Traversal of constructed tree " );
inorder(root);
|
Output
Inorder Traversal of constructed tree
6 5 3 1 4 0 2
Time Complexity: O(n), where n is the size of parent array
Auxiliary Space: O(n)
Method 3(using dictionary/hashmap)
Another method is to use a hash table to keep track of the nodes and their indices.
Algorithm
Create an empty hash table.
Traverse the parent array from left to right.
For each node in the parent array, get its parent index.
If the parent index is -1, create a new node and set it as the root.
Otherwise, check if the parent index is present in the hash table.
If it is, create a new node and add it as a child of the parent node.
Otherwise, create the parent node and add it to the hash table with its index as the key.
Repeat steps 3 to 7 for all the nodes in the parent array.
C++
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
class Node {
public :
int val;
Node* left;
Node* right;
Node( int val) : val(val), left(nullptr), right(nullptr) {}
};
void inorder(Node* node) {
if (node != nullptr) {
inorder(node->left);
cout << node->val << " " ;
inorder(node->right);
}
}
Node* create_tree(vector< int >& parent) {
int n = parent.size();
unordered_map< int , Node*> nodes;
Node* root = nullptr;
for ( int i = 0; i < n; ++i) {
if (parent[i] == -1) {
root = new Node(i);
nodes[i] = root;
} else {
Node* parentNode = nodes[parent[i]];
if (!parentNode) {
parentNode = new Node(parent[i]);
nodes[parent[i]] = parentNode;
}
Node* currentNode = new Node(i);
if (!parentNode->left) {
parentNode->left = currentNode;
} else {
parentNode->right = currentNode;
}
nodes[i] = currentNode;
}
}
return root;
}
int main() {
vector< int > parent = {-1, 0, 0, 1, 1, 3, 5};
Node* root = create_tree(parent);
cout << "Inorder traversal of constructed tree:" << endl;
inorder(root);
return 0;
}
|
Java
import java.util.*;
class Node {
int val;
Node left;
Node right;
Node( int val)
{
this .val = val;
left = null ;
right = null ;
}
}
public class GFG {
static void inorder(Node node)
{
if (node != null ) {
inorder(node.left);
System.out.print(node.val + " " );
inorder(node.right);
}
}
static Node createTree(List<Integer> parent)
{
int n = parent.size();
Map<Integer, Node> nodes
= new HashMap<>();
Node root = null ;
for ( int i = 0 ; i < n; ++i) {
if (parent.get(i) == - 1 ) {
root = new Node(i);
nodes.put(i, root);
}
else {
Node parentNode = nodes.get(parent.get(
i));
if (parentNode == null ) {
parentNode = new Node(
parent.get(i));
nodes.put(parent.get(i), parentNode);
}
Node currentNode
= new Node(i);
if (parentNode.left == null ) {
parentNode.left
= currentNode;
}
else {
parentNode.right
= currentNode;
}
nodes.put(
i,
currentNode);
}
}
return root;
}
public static void main(String[] args)
{
List<Integer> parent = Arrays.asList(
- 1 , 0 , 0 , 1 , 1 , 3 , 5 );
Node root = createTree(
parent);
System.out.println(
"Inorder traversal of constructed tree:" );
inorder(root);
}
}
|
Python3
class Node:
def __init__( self , val):
self .val = val
self .left = None
self .right = None
def inorder(node):
if node is not None :
inorder(node.left)
print (node.val, end = ' ' )
inorder(node.right)
def create_tree(parent):
n = len (parent)
nodes = {}
root = None
for i in range (n):
if parent[i] = = - 1 :
root = Node(i)
nodes[i] = root
else :
parent_node = nodes.get(parent[i], None )
if parent_node is None :
parent_node = Node(parent[i])
nodes[parent[i]] = parent_node
current_node = Node(i)
if parent_node.left is None :
parent_node.left = current_node
else :
parent_node.right = current_node
nodes[i] = current_node
return root
parent = [ - 1 , 0 , 0 , 1 , 1 , 3 , 5 ]
root = create_tree(parent)
print ( "Inorder traversal of constructed tree:" )
inorder(root)
|
C#
using System;
using System.Collections.Generic;
class Node {
public int val;
public Node left;
public Node right;
public Node( int val)
{
this .val = val;
left = null ;
right = null ;
}
}
public class GFG {
static void Inorder(Node node)
{
if (node != null ) {
Inorder(node.left);
Console.Write(node.val + " " );
Inorder(node.right);
}
}
static Node CreateTree(List< int > parent)
{
int n = parent.Count;
Dictionary< int , Node> nodes
= new Dictionary< int ,
Node>();
Node root = null ;
for ( int i = 0; i < n; ++i) {
if (parent[i] == -1) {
root = new Node(i);
nodes[i] = root;
}
else {
Node parentNode
= nodes.ContainsKey(parent[i])
? nodes[parent[i]]
: null ;
if (parentNode == null ) {
parentNode = new Node(
parent[i]);
nodes[parent[i]] = parentNode;
}
Node currentNode
= new Node(i);
if (parentNode.left == null ) {
parentNode.left
= currentNode;
}
else {
parentNode.right
= currentNode;
}
nodes[i] = currentNode;
}
}
return root;
}
static void Main()
{
List< int > parent = new List< int >{
-1, 0, 0, 1, 1, 3, 5
};
Node root = CreateTree(
parent);
Console.WriteLine(
"Inorder traversal of constructed tree:" );
Inorder(root);
}
}
|
Javascript
class Node {
constructor(val) {
this .val = val;
this .left = null ;
this .right = null ;
}
}
function inorder(node) {
if (node !== null ) {
inorder(node.left);
console.log(node.val + ' ' );
inorder(node.right);
}
}
function create_tree(parent) {
const n = parent.length;
const nodes = {};
let root = null ;
for (let i = 0; i < n; i++) {
if (parent[i] === -1) {
root = new Node(i);
nodes[i] = root;
} else {
let parent_node = nodes[parent[i]] || null ;
if (!parent_node) {
parent_node = new Node(parent[i]);
nodes[parent[i]] = parent_node;
}
const current_node = new Node(i);
if (parent_node.left === null ) {
parent_node.left = current_node;
} else {
parent_node.right = current_node;
}
nodes[i] = current_node;
}
}
return root;
}
const parent = [-1, 0, 0, 1, 1, 3, 5];
const root = create_tree(parent);
console.log( "Inorder traversal of constructed tree:" );
inorder(root);
|
Output
Inorder traversal of constructed tree:
6 5 3 1 4 0 2
Time complexity: O(n), since we need to visit each node of the tree exactly once.
Space complexity: O(h), where h is the height of the tree
Similar Problem: Find Height of Binary Tree represented by Parent array
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
20 Oct, 2023
Like Article
Save Article