Construct a Perfect Binary Tree from Preorder Traversal
Last Updated :
20 Oct, 2021
Given an array pre[], representing the Preorder traversal of a Perfect Binary Tree consisting of N nodes, the task is to construct a Perfect Binary Tree from the given Preorder Traversal and return the root of the tree.
Examples:
Input: pre[] = {1, 2, 4, 5, 3, 6, 7}
Output:
1
/ \
/ \
2 3
/ \ / \
/ \ / \
4 5 6 7
Input: pre[] = {1, 2, 3}
Output:
1
/ \
/ \
2 3
Generally to construct a binary tree, we can not do it by only using the preorder traversal, but here an extra condition is given that the binary tree is Perfect binary tree. We can use that extra condition.
For Perfect binary tree every node has either 2 or 0 children , and all the leaf nodes are present at same level. And the preorder traversal of a binary tree contains the root first, then the preorder traversal of the left subtree, then the preorder traversal of the right subtree . So for Perfect binary tree root should have same numbers of children in both subtrees , so the number ( say, n) of elements after the root in the preorder traversal should be even (2 * number of nodes in one subtree , as it is Perfect binary tree) . And since each subtrees have equal number of nodes for Perfect binary tree, we can find the preorder traversal of the left subtree (which is half of the array after the root in preorder traversal of the whole tree), and we know the preorder traversal of the right subtree must be after the preorder traversal of the left subtree, so rest half is the preorder traversal of the right subtree.
So the first element in the preorder traversal is the root, we will build a node as the root with this element , then we can easily find the preorder traversals of the left and right subtrees of the root, and we will recursively build the left and right subtrees of the root.
Approach: The given problem can be solved using recursion. Follow the steps below to solve the problem:
- Create a function, say BuildPerfectBT_helper with parameters as preStart, preEnd, pre[] where preStart represent starting index of the array pre[] and preEnd represents the ending index of the array pre[] and perform the following steps:
- If the value of preStart is greater than preEnd, then return NULL.
- Initialize root as pre[preStart].
- If the value of preStart is the same as the preEnd, then return root.
- Initialize 4 variable, say leftPreStart as preStart + 1, rightPreStart as leftPreStart + (preEnd – leftPreStart+1)/2, leftPreEnd as rightPreStart – 1 and rightPreEnd as preEnd.
- Modify the value of root->left by recursively calling the function buildPerfectBT_helper() with the parameters leftPreStart, leftPreEnd and pre[].
- Modify the value of root->right by recursively calling the function buildPerfectBT_helper() with the parameters rightPreStart, rightPreEnd and pre[].
- After performing the above steps, return root.
- After creating the Perfect Binary Tree, print the Inorder traversal of the tree.
Below is the illustration of the above steps discussed:
Step 1: build([1, 2, 4, 5, 3, 6, 7])
Step 2:
1
/ \
/ \
build([2, 4, 5]) build([3, 6, 7])
Now first element (1 here) is root, then the subarray after the first element ( which is [2,4,5,3,6,7] here ) contains the preorder traversals of the left and right subtrees. And we know left subtree’s preorder traversal is first half , i.e, [2,4,5] , and the right subtree’s preorder traversal is the second half , i.e, [3,6,7]. Now recursively build the left and right subtrees.
Step 3:
1
___________|_________________
/ \
/ \
2 3
______/___________ _______\____________
/ \ / \
/ \ / \
build([4]) build([5]) build([6]) build([7])
Step 4:
1
/ \
/ \
2 3
/ \ / \
/ \ / \
4 5 6 7
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *left, *right;
Node( int val)
{
data = val;
left = right = NULL;
}
};
Node* getNewNode( int val)
{
Node* newNode = new Node(val);
newNode->data = val;
newNode->left = newNode->right = NULL;
return newNode;
}
Node* buildPerfectBT_helper( int preStart,
int preEnd,
int pre[])
{
if (preStart > preEnd)
return NULL;
Node* root = getNewNode(pre[preStart]);
;
if (preStart == preEnd)
return root;
int leftPreStart = preStart + 1;
int rightPreStart = leftPreStart
+ (preEnd - leftPreStart + 1) / 2;
int leftPreEnd = rightPreStart - 1;
int rightPreEnd = preEnd;
root->left = buildPerfectBT_helper(
leftPreStart, leftPreEnd, pre);
root->right = buildPerfectBT_helper(
rightPreStart, rightPreEnd, pre);
return root;
}
Node* buildPerfectBT( int pre[], int size)
{
return buildPerfectBT_helper(0, size - 1, pre);
}
void printInorder(Node* root)
{
if (!root)
return ;
printInorder(root->left);
cout << root->data << " " ;
printInorder(root->right);
}
int main()
{
int pre[] = { 1, 2, 4, 5, 3, 6, 7 };
int N = sizeof (pre) / sizeof (pre[0]);
Node* root = buildPerfectBT(pre, N);
cout << "\nInorder traversal of the tree: " ;
printInorder(root);
return 0;
}
|
Java
public class Main
{
static class Node {
public int data;
public Node left, right;
public Node( int val)
{
data = val;
left = right = null ;
}
}
static Node getNewNode( int val)
{
Node newNode = new Node(val);
return newNode;
}
static Node buildPerfectBT_helper( int preStart, int preEnd, int [] pre)
{
if (preStart > preEnd)
return null ;
Node root = getNewNode(pre[preStart]);
if (preStart == preEnd)
return root;
int leftPreStart = preStart + 1 ;
int rightPreStart = leftPreStart + (preEnd - leftPreStart + 1 ) / 2 ;
int leftPreEnd = rightPreStart - 1 ;
int rightPreEnd = preEnd;
root.left = buildPerfectBT_helper(
leftPreStart, leftPreEnd, pre);
root.right = buildPerfectBT_helper(
rightPreStart, rightPreEnd, pre);
return root;
}
static Node buildPerfectBT( int [] pre, int size)
{
return buildPerfectBT_helper( 0 , size - 1 , pre);
}
static void printInorder(Node root)
{
if (root == null )
return ;
printInorder(root.left);
System.out.print(root.data + " " );
printInorder(root.right);
}
public static void main(String[] args) {
int [] pre = { 1 , 2 , 4 , 5 , 3 , 6 , 7 };
int N = pre.length;
Node root = buildPerfectBT(pre, N);
System.out.print( "Inorder traversal of the tree: " );
printInorder(root);
}
}
|
Python3
class Node:
def __init__( self , val):
self .data = val
self .left = None
self .right = None
def getNewNode(val):
newNode = Node(val)
return newNode
def buildPerfectBT_helper(preStart, preEnd, pre):
if (preStart > preEnd):
return None
root = getNewNode(pre[preStart])
if (preStart = = preEnd):
return root
leftPreStart = preStart + 1
rightPreStart = leftPreStart + int ((preEnd - leftPreStart + 1 ) / 2 )
leftPreEnd = rightPreStart - 1
rightPreEnd = preEnd
root.left = buildPerfectBT_helper(leftPreStart, leftPreEnd, pre)
root.right = buildPerfectBT_helper(rightPreStart, rightPreEnd, pre)
return root
def buildPerfectBT(pre, size):
return buildPerfectBT_helper( 0 , size - 1 , pre)
def printInorder(root):
if (root = = None ):
return
printInorder(root.left)
print (root.data, " ", end = " ")
printInorder(root.right)
pre = [ 1 , 2 , 4 , 5 , 3 , 6 , 7 ]
N = len (pre)
root = buildPerfectBT(pre, N)
print ( "Inorder traversal of the tree: " , end = "")
printInorder(root)
|
C#
using System;
using System.Collections.Generic;
class GFG {
class Node {
public int data;
public Node left, right;
public Node( int val)
{
data = val;
left = right = null ;
}
}
static Node getNewNode( int val)
{
Node newNode = new Node(val);
return newNode;
}
static Node buildPerfectBT_helper( int preStart, int preEnd, int [] pre)
{
if (preStart > preEnd)
return null ;
Node root = getNewNode(pre[preStart]);
if (preStart == preEnd)
return root;
int leftPreStart = preStart + 1;
int rightPreStart = leftPreStart + (preEnd - leftPreStart + 1) / 2;
int leftPreEnd = rightPreStart - 1;
int rightPreEnd = preEnd;
root.left = buildPerfectBT_helper(
leftPreStart, leftPreEnd, pre);
root.right = buildPerfectBT_helper(
rightPreStart, rightPreEnd, pre);
return root;
}
static Node buildPerfectBT( int [] pre, int size)
{
return buildPerfectBT_helper(0, size - 1, pre);
}
static void printInorder(Node root)
{
if (root == null )
return ;
printInorder(root.left);
Console.Write(root.data + " " );
printInorder(root.right);
}
static void Main() {
int [] pre = { 1, 2, 4, 5, 3, 6, 7 };
int N = pre.Length;
Node root = buildPerfectBT(pre, N);
Console.Write( "Inorder traversal of the tree: " );
printInorder(root);
}
}
|
Javascript
<script>
class Node
{
constructor(val) {
this .left = null ;
this .right = null ;
this .data = val;
}
}
function getNewNode(val)
{
let newNode = new Node(val);
return newNode;
}
function buildPerfectBT_helper(preStart, preEnd, pre)
{
if (preStart > preEnd)
return null ;
let root = getNewNode(pre[preStart]);
if (preStart == preEnd)
return root;
let leftPreStart = preStart + 1;
let rightPreStart = leftPreStart
+ parseInt((preEnd - leftPreStart + 1) / 2);
let leftPreEnd = rightPreStart - 1;
let rightPreEnd = preEnd;
root.left = buildPerfectBT_helper(
leftPreStart, leftPreEnd, pre);
root.right = buildPerfectBT_helper(
rightPreStart, rightPreEnd, pre);
return root;
}
function buildPerfectBT(pre, size)
{
return buildPerfectBT_helper(0, size - 1, pre);
}
function printInorder(root)
{
if (root == null )
return ;
printInorder(root.left);
document.write(root.data + " " );
printInorder(root.right);
}
let pre = [ 1, 2, 4, 5, 3, 6, 7 ];
let N = pre.length;
let root = buildPerfectBT(pre, N);
document.write( "Inorder traversal of the tree: " );
printInorder(root);
</script>
|
Output:
Inorder traversal of the tree: 4 2 5 1 6 3 7
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...