Open In App

Construct Full Binary Tree using its Preorder traversal and Preorder traversal of its mirror tree

Last Updated : 29 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two arrays that represent Preorder traversals of a full binary tree and its mirror tree, the task is to construct the binary tree using these two Preorder traversals. A Full Binary Tree is a binary tree where every node has either 0 or 2 children.

Note: It is not possible to construct a general binary tree using these two traversals. But we can create a full binary tree using the above traversals without any ambiguity. For more details refer to this article.

Examples: 

Input: pre[] = [1, 2, 4, 5, 3, 6, 7]
preMirror[] = [1, 3, 7, 6, 2, 5, 4]

Output:

construct-full-binary-tree-using-its-preorder-traversal-and-preorder-traversal-of-its-mirror-tree

Approach:

The idea is to recursively creates the root node from pre[], then searches for the next element in preM[] to split the subarrays for constructing the left and right subtrees. Inorder traversal is used to print the constructed tree.

Below is the implementation of above approach: 

C++
// C++ program to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree
#include <bits/stdc++.h>
using namespace std;


class Node {
public:
    int data;
    Node *left, *right;
    Node(int x) {
        data = x;
        left = right = nullptr;
    }
};

// A recursive function to construct a full binary tree
// from pre[] and preM[]. preIndex is used to keep 
// track of index in pre[]. l is low index and h is high 
// index for the current subarray in preM[].
Node* constructBinaryTreeUtil(vector<int> &pre, vector<int> &preM,
                              int &preIndex, int l, int h, int size) {
    // Base case
    if (preIndex >= size || l > h)
        return nullptr;

    // Create the root node using the current preIndex
    Node* root = new Node(pre[preIndex++]);

    // If the current subarray has only one element,
  	// no need to recurse
    if (l == h)
        return root;

    // Search the next element of pre[] in preM[]
    int i;
    for (i = l; i <= h; ++i)
        if (pre[preIndex] == preM[i])
            break;

    // Recursively construct left and
  	// right subtrees
    if (i <= h) {
        root->left = 
          constructBinaryTreeUtil(pre, preM, 
                                  preIndex, i, h, size);
        root->right = 
          constructBinaryTreeUtil(pre, preM, 
                                  preIndex, l + 1, i - 1, size);
    }

    return root;
}

// Function to construct the full binary tree using
// its preorder traversal and preorder traversal of its mirror tree.
Node* constructBinaryTree(vector<int> &pre, vector<int> &preMirror) {
    int preIndex = 0;
    int size = pre.size();

    Node *root = constructBinaryTreeUtil(pre, preMirror, 
                                         preIndex, 0, size - 1, size);
    return root;
}

void printInorder(Node* curr) {
    if (curr == nullptr)
        return;

    printInorder(curr->left);
    printf("%d ", curr->data);
    printInorder(curr->right);
}

int main() {
  
    vector<int> preOrder = {1, 2, 4, 5, 3, 6, 7};
    vector<int> preOrderMirror = {1, 3, 7, 6, 2, 5, 4};

    Node* root = 
      constructBinaryTree(preOrder, preOrderMirror); 
    printInorder(root); 

    return 0;
}
Java
// Java program to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree

import java.util.*;

class Node {
    int data;
    Node left, right;

    Node(int x) {
        data = x;
        left = right = null;
    }
}

class GfG {

    // A recursive function to construct a full binary tree
    // from pre[] and preM[]. preIndex is used to keep
    // track of index in pre[]. l is low index and h is high
    // index for the current subarray in preM[].
    static Node constructBinaryTreeUtil(List<Integer> pre,
                                        List<Integer> preM,
                                        int[] preIndex,
                                        int l, int h,
                                        int size) {
      
        if (preIndex[0] >= size || l > h)
            return null;

        // Create the root node using the
      	// current preIndex
        Node root = new Node(pre.get(preIndex[0]++));

        // If the current subarray has only one element, no
        // need to recurse
        if (l == h)
            return root;

        // Search the next element of pre[] in preM[]
        int i;
        for (i = l; i <= h; ++i)
            if (pre.get(preIndex[0]) == preM.get(i))
                break;

        // Recursively construct left and 
      	// right subtrees
        if (i <= h) {
            root.left = constructBinaryTreeUtil(
                pre, preM, preIndex, i, h, size);
            root.right = constructBinaryTreeUtil(
                pre, preM, preIndex, l + 1, i - 1, size);
        }

        return root;
    }

    // Function to construct the full binary tree using
    // its preorder traversal and preorder traversal of its
    // mirror tree.
    static Node constructBinaryTree(List<Integer> pre,
                                    List<Integer> preMirror) {
        int[] preIndex = {0};
        int size = pre.size();
        return constructBinaryTreeUtil(
            pre, preMirror, preIndex, 0, size - 1, size);
    }

    static void printInorder(Node curr) {
        if (curr == null)
            return;

        printInorder(curr.left);
        System.out.print(curr.data + " ");
        printInorder(curr.right);
    }

    public static void main(String[] args) {
      
        List<Integer> preOrder
            = Arrays.asList(1, 2, 4, 5, 3, 6, 7);
        List<Integer> preOrderMirror
            = Arrays.asList(1, 3, 7, 6, 2, 5, 4);

        Node root
            = constructBinaryTree(preOrder, preOrderMirror);
        printInorder(root);
    }
}
Python
# Python program to construct full binary tree
# using its preorder traversal and preorder
# traversal of its mirror tree
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

# A recursive function to construct a full binary tree
# from pre[] and preM[]. preIndex is used to keep
# track of index in pre[]. l is low index and h is high
# index for the current subarray in preM[].

def construct_binary_tree_util(pre, preM, preIndex, l, h, size):
  
    if preIndex[0] >= size or l > h:
        return None

    # Create the root node using the 
    # current preIndex
    root = Node(pre[preIndex[0]])
    preIndex[0] += 1

    # If the current subarray has only one 
    # element, no need to recurse
    if l == h:
        return root

    # Search the next element of pre[] in preM[]
    i = 0
    for i in range(l, h + 1):
        if pre[preIndex[0]] == preM[i]:
            break

    # Recursively construct left and right subtrees
    if i <= h:
        root.left = construct_binary_tree_util \
        			(pre, preM, preIndex, i, h, size)
        root.right = construct_binary_tree_util(
            pre, preM, preIndex, l + 1, i - 1, size)

    return root

# Function to construct the full binary tree using
# its preorder traversal and preorder traversal of its mirror tree.

def construct_binary_tree(pre, preMirror):
  
    preIndex = [0]
    size = len(pre)
    return construct_binary_tree_util(pre, preMirror, \
                                      preIndex, 0, size - 1, size)


def print_inorder(curr):
    if curr is None:
        return

    print_inorder(curr.left)
    print(f"{curr.data} ", end="")
    print_inorder(curr.right)


if __name__ == "__main__":
    preOrder = [1, 2, 4, 5, 3, 6, 7]
    preOrderMirror = [1, 3, 7, 6, 2, 5, 4]

    root = construct_binary_tree(preOrder, preOrderMirror)
    print_inorder(root)
C#
// C# program to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree

using System;
using System.Collections.Generic;

class Node {
    public int data;
    public Node left, right;

    public Node(int x) {
        data = x;
        left = right = null;
    }
}

class GfG {
  
    // A recursive function to construct a full binary tree
    // from pre[] and preM[]. preIndex is used to keep
    // track of index in pre[]. l is low index and h is high
    // index for the current subarray in preM[].
    static Node ConstructBinaryTreeUtil(List<int> pre,
                                        List<int> preM,
                                        ref int preIndex,
                                        int l, int h,
                                        int size) {

        if (preIndex >= size || l > h)
            return null;

        // Create the root node using the 
      	// current preIndex
        Node root = new Node(pre[preIndex++]);

        // If the current subarray has only one element, no
        // need to recurse
        if (l == h)
            return root;

        // Search the next element of pre[] in preM[]
        int i;
        for (i = l; i <= h; ++i)
            if (pre[preIndex] == preM[i])
                break;

        // Recursively construct left and 
     	//  right subtrees
        if (i <= h) {
            root.left = ConstructBinaryTreeUtil(
                pre, preM, ref preIndex, i, h, size);
            root.right = ConstructBinaryTreeUtil(
                pre, preM, ref preIndex, l + 1, i - 1,
                size);
        }

        return root;
    }

    // Function to construct the full binary tree using
    // its preorder traversal and preorder traversal of its
    // mirror tree.
    static Node ConstructBinaryTree(List<int> pre,
                                    List<int> preMirror) {
        int preIndex = 0;
        int size = pre.Count;
        return ConstructBinaryTreeUtil(pre, preMirror,
                                       ref preIndex, 0,
                                       size - 1, size);
    }

    static void PrintInorder(Node curr) {
        if (curr == null)
            return;

        PrintInorder(curr.left);
        Console.Write(curr.data + " ");
        PrintInorder(curr.right);
    }

    static void Main() {
      
        List<int> preOrder
            = new List<int>{ 1, 2, 4, 5, 3, 6, 7 };
        List<int> preOrderMirror
            = new List<int>{ 1, 3, 7, 6, 2, 5, 4 };

        Node root
            = ConstructBinaryTree(preOrder, preOrderMirror);
        PrintInorder(root);
    }
}
JavaScript
// JavaScript program to construct full binary tree
// using its preorder traversal and preorder
// traversal of its mirror tree

class Node {
    constructor(data) {
        this.data = data;
        this.left = this.right = null;
    }
}

// A recursive function to construct a full binary tree
// from pre[] and preM[]. preIndex is used to keep
// track of index in pre[]. l is low index and h is high
// index for the current subarray in preM[].
function constructBinaryTreeUtil(pre, preM, preIndex, l, h,
                                 size) {
    if (preIndex[0] >= size || l > h)
        return null;

    // Create the root node using the
    // current preIndex
    let root = new Node(pre[preIndex[0]]);
    preIndex[0]++;

    // If the current subarray has only one
    // element, no need to recurse
    if (l === h)
        return root;

    // Search the next element of pre[] 
    // in preM[]
    let i = 0;
    for (i = l; i <= h; ++i)
        if (pre[preIndex[0]] === preM[i])
            break;

    // Recursively construct left and 
    // right subtrees
    if (i <= h) {
        root.left = constructBinaryTreeUtil(
            pre, preM, preIndex, i, h, size);
        root.right = constructBinaryTreeUtil(
            pre, preM, preIndex, l + 1, i - 1, size);
    }

    return root;
}

// Function to construct the full binary tree using
// its preorder traversal and preorder traversal of its
// mirror tree.
function constructBinaryTree(pre, preMirror) {

    let preIndex =
        [ 0 ]; 
    let size = pre.length;
    return constructBinaryTreeUtil(pre, preMirror, preIndex,
                                   0, size - 1, size);
}

function printInorder(curr) {
    if (curr === null)
        return;

    printInorder(curr.left);
    console.log(curr.data + " ");
    printInorder(curr.right);
}

let preOrder = [ 1, 2, 4, 5, 3, 6, 7 ];
let preOrderMirror = [ 1, 3, 7, 6, 2, 5, 4 ];

let root = constructBinaryTree
			(preOrder, preOrderMirror);

printInorder(root);

Output
4 2 5 1 6 3 7 

Time Complexity: O(n^2), where n is number of nodes in tree.
Auxiliary Space: O(n)

If we observe carefully, then the reverse of the Preorder traversal of the mirror tree will be the Postorder traversal of the original tree. We can construct the tree from given Preorder and Postorder traversals in a similar manner as above. You can refer to Construct Full Binary Tree from given preorder and postorder traversals article on how to Construct a Full Binary Tree from given preorder and postorder traversals.



Next Article
Article Tags :
Practice Tags :

Similar Reads