Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

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

  • Difficulty Level : Hard
  • Last Updated : 18 Aug, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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

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)   
Output:
-1
0 1 2 3 4

 

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




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!