Given a set of parent nodes where the index of the array is the child of each Node value, the task is to insert the nodes as a forest(multiple trees combined together) where each parent could have more than two children. After inserting the nodes, print each level in a sorted format.
Example:
Input: arr[] = {5, 3, -1, 2, 5, 3}
Output:
-1
2
3
1 5
Input: arr[] = {-1, -1, -1, -1, -1, 1}
Output:
-1
0 1 2 3 4
5
Below is the explanation of the above examples:
-
Example 1:
- In this given array, the elements of the array will be the parent node and the array index will be the child nodes.
- Initially, we set the root of the forest to be -1 for reference.
- Now on traversing the array, we insert the nodes into the forest structure.
- Initially we identify the roots of the individual trees in the forest and insert them into the root of the forest.
- The index of -1 is 2. Print -1 and append 2 as child node.
- Now search the list for list value as 2. Index 3 has value 2. Therefore 3 becomes the child of 2.
- Now the indexes having value 3 are 1 and 5. So 1 and 5 are the children of 3.
- The list does not contain 1 so ignore 1.
- The index that contains 5 are 0 and 4. So they become the child.
- In this given array, the elements of the array will be the parent node and the array index will be the child nodes.
-1 ---------- root of the forest / 2 ---------- level (0) / 3 ---------- level (1) / \ 1 5 ---------- level (2) / \ 0 4 ---------- level (3) Note: level (0) contains roots of each tree
-
Example 2:
- In this case, the tree will be of the format
-1 -------- root of the forest / | | | \ 0 1 2 3 4 -------- level (0) | 5 -------- level (1) Note: level (0) contains roots of each tree
Prerequisite: Level order traversal.
Approach: The idea is to recursively insert nodes in a tree. However the tree structure is quite different, usually in the case of binary tree there will be a maximum of two child nodes for any node but in this case the root node can have N number of child nodes.’-1′ is considered as the root and the index of the root will be considered as child nodes.
Example:
If -1 is present in index 3 then 3 will be the child node of -1.
-1 / 3
Insert -1 into the queue. Now if the root is empty then -1 node becomes the root. Now dequeue and queue the child nodes of -1. Create nodes and append them with the root. Continue this till all the child nodes have been inserted.
Level order Traversal: -1 3 5 2 4 6 9 The output for level order traversal will be: -1 3 5 2 4 6 9
Same enqueue and dequeue approach is followed for traversing by level order.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
// Node creation class Node
{ public :
int val;
// Since n children are possible for a root.
// A list created to store all the children.
vector<Node *> child;
// Constructor
Node( int data) : val(data) {}
}; // Function to insert void insert(Node *root, int parent, Node *node)
{ // Root is empty then the node will
// become the root
if (!root)
{
root = node;
}
else
{
if (root->val == parent)
{
root->child.push_back(node);
}
else
{
// Recursive approach to
// insert the child
int l = root->child.size();
for ( int i = 0; i < l; i++)
{
if (root->child[i]->val == parent)
insert(root->child[i], parent, node);
else
insert(root->child[i], parent, node);
}
}
}
} // Function to perform level order traversal void levelorder(vector<Node *> &prev_level)
{ vector<Node *> cur_level;
vector< int > print_data;
int l = prev_level.size();
if (l == 0)
{
exit (0);
}
for ( int i = 0; i < l; i++)
{
int prev_level_len = prev_level[i]->child.size();
for ( int j = 0; j < prev_level_len; j++)
{
// enqueue all the children
// into cur_level list
cur_level.push_back(prev_level[i]->child[j]);
// Copies the entire cur_level
// list into prev_level
print_data.push_back(prev_level[i]->child[j]->val);
}
}
prev_level = cur_level;
for ( auto i : print_data)
{
cout << i << " " ;
}
levelorder(prev_level);
} // Function that calls levelorder method to // perform level order traversal void levelorder_root(Node *root)
{ if (root)
{
vector<Node *> level;
level.push_back(root);
printf ( "%d\n" , root->val);
levelorder(level);
}
} // Driver code int main( int argc, char const *argv[])
{ // -1 is the root element
int arr[] = {-1, -1, -1, -1, -1};
Node *root = new Node(-1);
int l = sizeof (arr) / sizeof ( int );
vector< int > que;
// Inserting root element to the queue
que.push_back(-1);
while ( true )
{
vector< int > temp;
for ( int i = 0; i < l; i++)
{
if (find(que.begin(),
que.end(), arr[i]) != que.end())
{
// Insert elements into the tree
insert(root, arr[i], new Node(i));
temp.push_back(i);
}
}
// Append child nodes into the queue
// and insert the child
que = temp;
if (que.size() == 0)
{
break ;
}
}
levelorder_root(root);
} // This code is contributed by sanjeev2552 |
import java.util.ArrayList;
import java.util.List;
class Node {
int val;
List<Node> child;
public Node( int data) {
val = data;
child = new ArrayList<>();
}
} class Tree {
static Node insert(Node root, int parent, Node node) {
if (root == null ) {
root = node;
} else {
if (root.val == parent) {
root.child.add(node);
} else {
for ( int i = 0 ; i < root.child.size(); i++) {
insert(root.child.get(i), parent, node);
}
}
}
return root;
}
static void levelorderRoot(Node root) {
if (root != null ) {
List<Node> level = new ArrayList<>();
level.add(root);
System.out.println(root.val);
levelorder(level);
}
}
static void levelorder(List<Node> prevLevel) {
List<Node> curLevel = new ArrayList<>();
List<Integer> printData = new ArrayList<>();
for ( int i = 0 ; i < prevLevel.size(); i++) {
for ( int j = 0 ; j < prevLevel.get(i).child.size(); j++) {
curLevel.add(prevLevel.get(i).child.get(j));
printData.add(prevLevel.get(i).child.get(j).val);
}
}
prevLevel = curLevel;
for ( int i : printData) {
System.out.print(i + " " );
}
System.out.println();
if (prevLevel.size() > 0 ) {
levelorder(prevLevel);
}
}
public static void main(String[] args) {
int [] arr = {- 1 , - 1 , - 1 , - 1 , - 1 };
Node root = new Node(- 1 );
List<Integer> que = new ArrayList<>();
que.add(- 1 );
while ( true ) {
List<Integer> temp = new ArrayList<>();
for ( int i = 0 ; i < arr.length; i++) {
if (que.contains(arr[i])) {
root = insert(root, arr[i], new Node(i));
temp.add(i);
}
}
que = temp;
if (que.size() == 0 ) {
break ;
}
}
levelorderRoot(root);
}
} // This code is contributed by aadityaburujwale. |
# Python3 implementation of the approach # Node creation class Node:
# Constructor
def __init__( self , data):
self .val = data
# Since n children are possible for a root.
# A list created to store all the children.
self .child = []
# Function to insert def insert(root, parent, node):
# Root is empty then the node will become the root
if root is None :
root = node
else :
if root.val = = parent:
root.child.append(node)
else :
# Recursive approach to
# insert the child
l = len (root.child)
for i in range (l):
if root.child[i].val = = parent:
insert(root.child[i], parent, node)
else :
insert(root.child[i], parent, node)
# Function that calls levelorder method to # perform level order traversal def levelorder_root(root):
if root:
level = []
level.append(root)
print (root.val)
levelorder(level)
# Function to perform level order traversal def levelorder(prev_level):
cur_level = []
print_data = []
l = len (prev_level)
if l = = 0 :
exit()
for i in range (l):
prev_level_len = len (prev_level[i].child)
for j in range (prev_level_len):
# enqueue all the children
# into cur_level list
cur_level.append(
prev_level[i].child[j])
# Copies the entire cur_level
# list into prev_level
print_data.append(
prev_level[i].child[j].val)
prev_level = cur_level[:]
print ( * print_data)
levelorder(prev_level)
# Driver code # -1 is the root element arr = [ - 1 , - 1 , - 1 , - 1 , - 1 ]
root = Node( - 1 )
l = len (arr)
que = []
# Inserting root element to the queue que.append( - 1 )
while 1 :
temp = []
for i in range (l):
if arr[i] in que:
# Insert elements into the tree
insert(root, arr[i], Node(i))
temp.append(i)
# Append child nodes into the queue
# and insert the child
que = temp[:]
if len (que) = = 0 :
break
levelorder_root(root) |
// JavaScript implementation of the approach class Node { constructor(val) {
this .val = val;
this .child = [];
}
} function insert(root, parent, node) {
// Root is empty then the node will
// become the root
if (!root) {
root = node;
} else {
if (root.val === parent) {
root.child.push(node);
} else {
// Recursive approach to
// insert the child
let l = root.child.length;
for (let i = 0; i < l; i++) {
if (root.child[i].val === parent) {
insert(root.child[i], parent, node);
} else {
insert(root.child[i], parent, node);
}
}
}
}
} function levelorder(prev_level) {
let cur_level = [];
let print_data = [];
let l = prev_level.length;
if (l === 0) {
return ;
}
for (let i = 0; i < l; i++) {
let prev_level_len = prev_level[i].child.length;
for (let j = 0; j < prev_level_len; j++) {
// enqueue all the children
// into cur_level list
cur_level.push(prev_level[i].child[j]);
// Copies the entire cur_level
// list into prev_level
print_data.push(prev_level[i].child[j].val);
}
}
prev_level = cur_level;
for (let i of print_data) {
console.log(i + " " );
}
levelorder(prev_level);
} function levelorder_root(root) {
if (root) {
let level = [];
level.push(root);
console.log(root.val);
levelorder(level);
}
} // -1 is the root element let arr = [-1, -1, -1, -1, -1]; let root = new Node(-1);
let l = arr.length; let que = []; // Inserting root element to the queue que.push(-1); while ( true ) {
let temp = [];
for (let i = 0; i < l; i++) {
if (que.includes(arr[i])) {
// Insert elements into the tree
insert(root, arr[i], new Node(i));
temp.push(i);
}
}
// Append child nodes into the queue
// and insert the child
que = temp;
if (que.length === 0) {
break ;
}
} levelorder_root(root); // This code is contributed by adityamaharshi21 |
//C# code for the above approach using System;
using System.Collections.Generic;
class Node
{ public int val;
public List<Node> child;
public Node( int data)
{
val = data;
child = new List<Node>();
}
} class Tree
{ static Node insert(Node root, int parent, Node node)
{
if (root == null )
{
root = node;
}
else
{
if (root.val == parent)
{
root.child.Add(node);
}
else
{
for ( int i = 0; i < root.child.Count; i++)
{
insert(root.child[i], parent, node);
}
}
}
return root;
}
static void levelorderRoot(Node root)
{
if (root != null )
{
List<Node> level = new List<Node>();
level.Add(root);
Console.WriteLine(root.val);
levelorder(level);
}
}
static void levelorder(List<Node> prevLevel)
{
List<Node> curLevel = new List<Node>();
List< int > printData = new List< int >();
for ( int i = 0; i < prevLevel.Count; i++)
{
for ( int j = 0; j < prevLevel[i].child.Count; j++)
{
curLevel.Add(prevLevel[i].child[j]);
printData.Add(prevLevel[i].child[j].val);
}
}
prevLevel = curLevel;
foreach ( int i in printData)
{
Console.Write(i + " " );
}
Console.WriteLine();
if (prevLevel.Count > 0)
{
levelorder(prevLevel);
}
}
static void Main( string [] args)
{
int [] arr = { -1, -1, -1, -1, -1 };
Node root = new Node(-1);
List< int > que = new List< int >();
que.Add(-1);
while ( true )
{
List< int > temp = new List< int >();
for ( int i = 0; i < arr.Length; i++)
{
if (que.Contains(arr[i]))
{
root = insert(root, arr[i], new Node(i));
temp.Add(i);
}
}
que = temp;
if (que.Count == 0)
{
break ;
}
}
levelorderRoot(root);
}
} //This code is contributed by Potta Lokesh |
-1 0 1 2 3 4
Time Complexity: O(N^2).
Auxiliary Space: O(N).