Skip to content
Related Articles
Open in App
Not now

Related Articles

Insertion in n-ary tree in given order and Level order traversal

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 10 Jan, 2023
Improve Article
Save Article

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.
        -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++




// 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

Java




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




# 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




// 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#




//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

Output:

-1
0 1 2 3 4

 

Time Complexity: O(N^2). 
Auxiliary Space: O(N).  


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!