Given a Preorder traversal of a Binary Search Tree. The task is to print leaf nodes of the Binary Search Tree from the given preorder.
Examples:
Input : preorder[] = {890, 325, 290, 530, 965};
Output : 290 530 965
Explanation : Tree represented is,
890
/ \
325 965
/ \
290 530
Input : preorder[] = { 3, 2, 4 };
Output : 2 4
Method 1: (Simple):
The idea is to find Iorder, then traverse the tree in preorder fashion (using both inorder and postorder traversals) and while traversing print leaf nodes.
How to traverse in preorder fashion using two arrays representing inorder and preorder traversals?
We iterate the preorder array and for each element find that element in the inorder array. For searching, we can use binary search, since inorder traversal of the binary search tree is always sorted. Now, for each element of preorder array, in binary search, we set the range [L, R].
And when L == R, the leaf node is found. So, initially, L = 0 and R = n – 1 for first element (i.e root) of preorder array. Now, to search for the element on the left subtree of the root, set L = 0 and R = index of root – 1. Also, for all element of right subtree set L = index of root + 1 and R = n -1.
Recursively, follow this, until L == R.
Below is the implementation of this approach:
C++
#include<bits/stdc++.h>
using namespace std;
int binarySearch( int inorder[], int l, int r, int d)
{
int mid = (l + r)>>1;
if (inorder[mid] == d)
return mid;
else if (inorder[mid] > d)
return binarySearch(inorder, l, mid - 1, d);
else
return binarySearch(inorder, mid + 1, r, d);
}
void leafNodesRec( int preorder[], int inorder[],
int l, int r, int *ind, int n)
{
if (l == r)
{
printf ( "%d " , inorder[l]);
*ind = *ind + 1;
return ;
}
if (l < 0 || l > r || r >= n)
return ;
int loc = binarySearch(inorder, l, r, preorder[*ind]);
*ind = *ind + 1;
leafNodesRec(preorder, inorder, l, loc - 1, ind, n);
leafNodesRec(preorder, inorder, loc + 1, r, ind, n);
}
void leafNodes( int preorder[], int n)
{
int inorder[n];
for ( int i = 0; i < n; i++)
inorder[i] = preorder[i];
sort(inorder, inorder + n);
int ind = 0;
leafNodesRec(preorder, inorder, 0, n - 1, &ind, n);
}
int main()
{
int preorder[] = { 890, 325, 290, 530, 965 };
int n = sizeof (preorder)/ sizeof (preorder[0]);
leafNodes(preorder, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int binarySearch( int inorder[], int l,
int r, int d)
{
int mid = (l + r) >> 1 ;
if (inorder[mid] == d)
return mid;
else if (inorder[mid] > d)
return binarySearch(inorder, l,
mid - 1 , d);
else
return binarySearch(inorder,
mid + 1 , r, d);
}
static int ind;
static void leafNodesRec( int preorder[],
int inorder[],
int l, int r, int n)
{
if (l == r)
{
System.out.printf( "%d " , inorder[l]);
ind = ind + 1 ;
return ;
}
if (l < 0 || l > r || r >= n)
return ;
int loc = binarySearch(inorder, l, r,
preorder[ind]);
ind = ind + 1 ;
leafNodesRec(preorder, inorder,
l, loc - 1 , n);
leafNodesRec(preorder, inorder,
loc + 1 , r, n);
}
static void leafNodes( int preorder[], int n)
{
int inorder[] = new int [n];
for ( int i = 0 ; i < n; i++)
inorder[i] = preorder[i];
Arrays.sort(inorder);
leafNodesRec(preorder, inorder, 0 , n - 1 , n);
}
public static void main(String args[])
{
int preorder[] = { 890 , 325 , 290 , 530 , 965 };
int n = preorder.length;
leafNodes(preorder, n);
}
}
|
Python3
def binarySearch(inorder, l, r, d):
mid = (l + r) >> 1
if (inorder[mid] = = d):
return mid
elif (inorder[mid] > d):
return binarySearch(inorder, l,
mid - 1 , d)
else :
return binarySearch(inorder,
mid + 1 , r, d)
def leafNodesRec(preorder, inorder,
l, r, ind, n):
if (l = = r):
print (inorder[l], end = " " )
ind[ 0 ] = ind[ 0 ] + 1
return
if (l < 0 or l > r or r > = n):
return
loc = binarySearch(inorder, l, r,
preorder[ind[ 0 ]])
ind[ 0 ] = ind[ 0 ] + 1
leafNodesRec(preorder, inorder,
l, loc - 1 , ind, n)
leafNodesRec(preorder, inorder,
loc + 1 , r, ind, n)
def leafNodes(preorder, n):
inorder = [ 0 ] * n
for i in range (n):
inorder[i] = preorder[i]
inorder.sort()
ind = [ 0 ]
leafNodesRec(preorder, inorder, 0 ,
n - 1 , ind, n)
preorder = [ 890 , 325 , 290 , 530 , 965 ]
n = len (preorder)
leafNodes(preorder, n)
|
C#
using System;
class GFG
{
static int binarySearch( int []inorder, int l,
int r, int d)
{
int mid = (l + r) >> 1;
if (inorder[mid] == d)
return mid;
else if (inorder[mid] > d)
return binarySearch(inorder, l,
mid - 1, d);
else
return binarySearch(inorder,
mid + 1, r, d);
}
static int ind;
static void leafNodesRec( int []preorder,
int []inorder,
int l, int r, int n)
{
if (l == r)
{
Console.Write( "{0} " , inorder[l]);
ind = ind + 1;
return ;
}
if (l < 0 || l > r || r >= n)
return ;
int loc = binarySearch(inorder, l, r,
preorder[ind]);
ind = ind + 1;
leafNodesRec(preorder, inorder,
l, loc - 1, n);
leafNodesRec(preorder, inorder,
loc + 1, r, n);
}
static void leafNodes( int []preorder, int n)
{
int []inorder = new int [n];
for ( int i = 0; i < n; i++)
inorder[i] = preorder[i];
Array.Sort(inorder);
leafNodesRec(preorder, inorder, 0, n - 1, n);
}
public static void Main(String []args)
{
int []preorder = { 890, 325, 290, 530, 965 };
int n = preorder.Length;
leafNodes(preorder, n);
}
}
|
Javascript
<script>
function binarySearch(inorder, l, r, d) {
var mid = parseInt((l + r) / 2);
if (inorder[mid] == d) return mid;
else if (inorder[mid] > d)
return binarySearch(inorder, l, mid - 1, d);
else
return binarySearch(inorder, mid + 1, r, d);
}
var ind = 0;
function leafNodesRec(preorder, inorder, l, r, n) {
if (l == r) {
document.write(inorder[l] + " " );
ind = ind + 1;
return ;
}
if (l < 0 || l > r || r >= n) return ;
var loc = binarySearch(inorder, l, r, preorder[ind]);
ind = ind + 1;
leafNodesRec(preorder, inorder, l, loc - 1, n);
leafNodesRec(preorder, inorder, loc + 1, r, n);
}
function leafNodes(preorder, n) {
var inorder = new Array(n).fill(0);
for ( var i = 0; i < n; i++) inorder[i] = preorder[i];
inorder.sort();
leafNodesRec(preorder, inorder, 0, n - 1, n);
}
var preorder = [890, 325, 290, 530, 965];
var n = preorder.length;
leafNodes(preorder, n);
</script>
|
Time Complexity: O(n log n)
Auxiliary Space: O(n)
Method 2:(using Stack):
The idea is to use the property of the Binary Search Tree and stack.
Traverse the array using two pointer i and j to the array, initially i = 0 and j = 1. Whenever a[i] > a[j], we can say a[j] is left part of a[i], since preorder traversal follows Visit -> Left -> Right. So, we push a[i] into the stack.
For those points violating the rule, we start to pop element from the stack till a[i] > top element of the stack and break when it doesn’t and print the corresponding jth value.
Algorithm:
1. Set i = 0, j = 1.
2. Traverse the preorder array.
3. If a[i] > a[j], push a[i] to the stack.
4. Else
While (stack is not empty)
if (a[j] > top of stack)
pop element from the stack;
set found = true;
else
break;
5. if (found == true)
print a[i];
How does this algorithm work?
Preorder traversal traverse in the order: Visit, Left, Right.
And we know the left node of any node in BST is always less than the node. So preorder traversal will first traverse from root to leftmost node. Therefore, preorder will be in decreasing order first. Now, after decreasing order, there may be a node that is greater or which breaks the decreasing order. So, there can be a case like this :

In case 1, 20 is a leaf node whereas in case 2, 20 is not the leaf node.
So, our problem is how to identify if we have to print 20 as a leaf node or not?
This is solved using stack.
While running above algorithm on case 1 and case 2, when i = 2 and j = 3, state of a stack will be the same in both the case :

So, node 65 will pop 20 and 50 from the stack. This is because 65 is the right child of a node which is before 20. This information we store using the found variable. So, 20 is a root node.
While in case 2, 40 will not able to pop any element from the stack. Because 40 is the right node of a node which is after 20. So, 20 is not a leaf node.
Note: In the algorithm, we will not be able to check the condition of the leaf node of the rightmost node or rightmost element of the preorder. So, simply print the rightmost node because we know this will always be a leaf node in preorder traversal.
Below is the implementation of this approach:
C++
#include<bits/stdc++.h>
using namespace std;
void leafNode( int preorder[], int n)
{
stack< int > s;
for ( int i = 0, j = 1; j < n; i++, j++)
{
bool found = false ;
if (preorder[i] > preorder[j])
s.push(preorder[i]);
else
{
while (!s.empty())
{
if (preorder[j] > s.top())
{
s.pop();
found = true ;
}
else
break ;
}
}
if (found)
cout << preorder[i] << " " ;
}
cout << preorder[n - 1];
}
int main()
{
int preorder[] = { 890, 325, 290, 530, 965 };
int n = sizeof (preorder)/ sizeof (preorder[0]);
leafNode(preorder, n);
return 0;
}
|
Java
import java.util.*;
class GfG {
static void leafNode( int preorder[], int n)
{
Stack<Integer> s = new Stack<Integer> ();
for ( int i = 0 , j = 1 ; j < n; i++, j++)
{
boolean found = false ;
if (preorder[i] > preorder[j])
s.push(preorder[i]);
else
{
while (!s.isEmpty())
{
if (preorder[j] > s.peek())
{
s.pop();
found = true ;
}
else
break ;
}
}
if (found)
System.out.print(preorder[i] + " " );
}
System.out.println(preorder[n - 1 ]);
}
public static void main(String[] args)
{
int preorder[] = { 890 , 325 , 290 , 530 , 965 };
int n = preorder.length;
leafNode(preorder, n);
}
}
|
Python3
def leafNode(preorder, n):
s = []
i = 0
for j in range ( 1 , n):
found = False
if preorder[i] > preorder[j]:
s.append(preorder[i])
else :
while len (s) ! = 0 :
if preorder[j] > s[ - 1 ]:
s.pop( - 1 )
found = True
else :
break
if found:
print (preorder[i], end = " " )
i + = 1
print (preorder[n - 1 ])
if __name__ = = '__main__' :
preorder = [ 890 , 325 , 290 , 530 , 965 ]
n = len (preorder)
leafNode(preorder, n)
|
C#
using System;
using System.Collections.Generic;
public class GfG
{
public static void leafNode( int [] preorder, int n)
{
Stack< int > s = new Stack< int > ();
for ( int i = 0, j = 1; j < n; i++, j++)
{
bool found = false ;
if (preorder[i] > preorder[j])
{
s.Push(preorder[i]);
}
else
{
while (s.Count > 0)
{
if (preorder[j] > s.Peek())
{
s.Pop();
found = true ;
}
else
{
break ;
}
}
}
if (found)
{
Console.Write(preorder[i] + " " );
}
}
Console.WriteLine(preorder[n - 1]);
}
public static void Main( string [] args)
{
int [] preorder = new int [] {890, 325, 290, 530, 965};
int n = preorder.Length;
leafNode(preorder, n);
}
}
|
Javascript
<script>
function leafNode(preorder, n)
{
let s = [];
for (let i = 0, j = 1; j < n; i++, j++)
{
let found = false ;
if (preorder[i] > preorder[j])
s.push(preorder[i]);
else
{
while (s.length > 0)
{
if (preorder[j] > s[s.length - 1])
{
s.pop();
found = true ;
}
else
break ;
}
}
if (found)
document.write(preorder[i] + " " );
}
document.write(preorder[n - 1]);
}
let preorder = [ 890, 325, 290, 530, 965 ];
let n = preorder.length;
leafNode(preorder, n);
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Leaf nodes from Preorder of a Binary Search Tree (Using Recursion)
This article is contributed by Anuj Chauhan. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.