Given a Binary Tree, write an iterative function to print the Preorder traversal of the given binary tree.
Refer to this for recursive preorder traversal of Binary Tree. To convert an inherently recursive procedure to iterative, we need an explicit stack.
Following is a simple stack based iterative process to print Preorder traversal.
- Create an empty stack nodeStack and push root node to stack.
- Do the following while nodeStack is not empty.
- Pop an item from the stack and print it.
- Push right child of a popped item to stack
- Push left child of a popped item to stack
The right child is pushed before the left child to make sure that the left subtree is processed first.
C++
#include <bits/stdc++.h>
using namespace std;
struct node {
int data;
struct node* left;
struct node* right;
};
struct node* newNode( int data)
{
struct node* node = new struct node;
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
void iterativePreorder(node* root)
{
if (root == NULL)
return ;
stack<node*> nodeStack;
nodeStack.push(root);
while (nodeStack.empty() == false ) {
struct node* node = nodeStack.top();
printf ( "%d " , node->data);
nodeStack.pop();
if (node->right)
nodeStack.push(node->right);
if (node->left)
nodeStack.push(node->left);
}
}
int main()
{
struct node* root = newNode(10);
root->left = newNode(8);
root->right = newNode(2);
root->left->left = newNode(3);
root->left->right = newNode(5);
root->right->left = newNode(2);
iterativePreorder(root);
return 0;
}
|
Java
import java.util.Stack;
class Node {
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree {
Node root;
void iterativePreorder()
{
iterativePreorder(root);
}
void iterativePreorder(Node node)
{
if (node == null ) {
return ;
}
Stack<Node> nodeStack = new Stack<Node>();
nodeStack.push(root);
while (nodeStack.empty() == false ) {
Node mynode = nodeStack.peek();
System.out.print(mynode.data + " " );
nodeStack.pop();
if (mynode.right != null ) {
nodeStack.push(mynode.right);
}
if (mynode.left != null ) {
nodeStack.push(mynode.left);
}
}
}
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 10 );
tree.root.left = new Node( 8 );
tree.root.right = new Node( 2 );
tree.root.left.left = new Node( 3 );
tree.root.left.right = new Node( 5 );
tree.root.right.left = new Node( 2 );
tree.iterativePreorder();
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def iterativePreorder(root):
if root is None :
return
nodeStack = []
nodeStack.append(root)
while ( len (nodeStack) > 0 ):
node = nodeStack.pop()
print (node.data, end = " " )
if node.right is not None :
nodeStack.append(node.right)
if node.left is not None :
nodeStack.append(node.left)
root = Node( 10 )
root.left = Node( 8 )
root.right = Node( 2 )
root.left.left = Node( 3 )
root.left.right = Node( 5 )
root.right.left = Node( 2 )
iterativePreorder(root)
|
C#
using System;
using System.Collections.Generic;
public class Node {
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class GFG {
public Node root;
public virtual void iterativePreorder()
{
iterativePreorder(root);
}
public virtual void iterativePreorder(Node node)
{
if (node == null ) {
return ;
}
Stack<Node> nodeStack = new Stack<Node>();
nodeStack.Push(root);
while (nodeStack.Count > 0) {
Node mynode = nodeStack.Peek();
Console.Write(mynode.data + " " );
nodeStack.Pop();
if (mynode.right != null ) {
nodeStack.Push(mynode.right);
}
if (mynode.left != null ) {
nodeStack.Push(mynode.left);
}
}
}
public static void Main( string [] args)
{
GFG tree = new GFG();
tree.root = new Node(10);
tree.root.left = new Node(8);
tree.root.right = new Node(2);
tree.root.left.left = new Node(3);
tree.root.left.right = new Node(5);
tree.root.right.left = new Node(2);
tree.iterativePreorder();
}
}
|
Javascript
<script>
class Node
{
constructor(item)
{
this .data = item;
this .left = null ;
this .right = null ;
}
}
var root = null ;
function iterativePreorder(node)
{
if (node == null )
{
return ;
}
var nodeStack = [];
nodeStack.push(root);
while (nodeStack.length > 0)
{
var mynode = nodeStack[nodeStack.length - 1];
document.write(mynode.data + " " );
nodeStack.pop();
if (mynode.right != null )
{
nodeStack.push(mynode.right);
}
if (mynode.left != null )
{
nodeStack.push(mynode.left);
}
}
}
root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(2);
iterativePreorder(root);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(H), where H is the height of the tree.
Another Solution: In the previous solution we can see that the left child is popped as soon as it is pushed to the stack, therefore it is not required to push it into the stack.
The idea is to start traversing the tree from the root node, and keep printing the left child while exists and simultaneously, push the right child of every node in an auxiliary stack. Once we reach a null node, pop a right child from the auxiliary stack and repeat the process while the auxiliary stack is not-empty.
This is a micro-optimization over the previous approach, both the solutions use asymptotically similar auxiliary space.
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 data)
{
this ->data = data;
this ->left = this ->right = NULL;
}
};
void preorderIterative(Node* root)
{
if (root == NULL)
return ;
stack<Node*> st;
Node* curr = root;
while (!st.empty() || curr != NULL) {
while (curr != NULL) {
cout << curr->data << " " ;
if (curr->right)
st.push(curr->right);
curr = curr->left;
}
if (st.empty() == false ) {
curr = st.top();
st.pop();
}
}
}
int main()
{
Node* root = new Node(10);
root->left = new Node(20);
root->right = new Node(30);
root->left->left = new Node(40);
root->left->left->left = new Node(70);
root->left->right = new Node(50);
root->right->left = new Node(60);
root->left->left->right = new Node(80);
preorderIterative(root);
return 0;
}
|
Java
import java.util.Stack;
class Node
{
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree{
Node root;
void preorderIterative()
{
preorderIterative(root);
}
void preorderIterative(Node node)
{
if (node == null )
{
return ;
}
Stack<Node> st = new Stack<Node>();
Node curr = node;
while (curr != null || !st.isEmpty())
{
while (curr != null )
{
System.out.print(curr.data + " " );
if (curr.right != null )
st.push(curr.right);
curr = curr.left;
}
if (!st.isEmpty())
{
curr = st.pop();
}
}
}
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 10 );
tree.root.left = new Node( 20 );
tree.root.right = new Node( 30 );
tree.root.left.left = new Node( 40 );
tree.root.left.left.left = new Node( 70 );
tree.root.left.right = new Node( 50 );
tree.root.right.left = new Node( 60 );
tree.root.left.left.right = new Node( 80 );
tree.preorderIterative();
}
}
|
Python3
class Node:
def __init__( self , data = 0 ):
self .data = data
self .left = None
self .right = None
def preorderIterative(root):
if (root = = None ):
return
st = []
curr = root
while ( len (st) or curr ! = None ):
while (curr ! = None ):
print (curr.data, end = " " )
if (curr.right ! = None ):
st.append(curr.right)
curr = curr.left
if ( len (st) > 0 ):
curr = st[ - 1 ]
st.pop()
root = Node( 10 )
root.left = Node( 20 )
root.right = Node( 30 )
root.left.left = Node( 40 )
root.left.left.left = Node( 70 )
root.left.right = Node( 50 )
root.right.left = Node( 60 )
root.left.left.right = Node( 80 )
preorderIterative(root)
|
C#
using System;
using System.Collections.Generic;
public class Node
{
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
public class BinaryTree{
Node root;
void preorderIterative()
{
preorderIterative(root);
}
void preorderIterative(Node node)
{
if (node == null )
{
return ;
}
Stack<Node> st = new Stack<Node>();
Node curr = node;
while (curr != null || st.Count!=0)
{
while (curr != null )
{
Console.Write(curr.data + " " );
if (curr.right != null )
st.Push(curr.right);
curr = curr.left;
}
if (st.Count != 0)
{
curr = st.Pop();
}
}
}
public static void Main(String []args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(10);
tree.root.left = new Node(20);
tree.root.right = new Node(30);
tree.root.left.left = new Node(40);
tree.root.left.left.left = new Node(70);
tree.root.left.right = new Node(50);
tree.root.right.left = new Node(60);
tree.root.left.left.right = new Node(80);
tree.preorderIterative();
}
}
|
Javascript
<script>
class Node
{
constructor(item)
{
this .left = null ;
this .right = null ;
this .data = item;
}
}
let root;
function preorderiterative(node)
{
if (node == null )
{
return ;
}
let st = [];
let curr = node;
while (curr != null || st.length > 0)
{
while (curr != null )
{
document.write(curr.data + " " );
if (curr.right != null )
st.push(curr.right);
curr = curr.left;
}
if (st.length > 0)
{
curr = st.pop();
}
}
}
function preorderIterative()
{
preorderiterative(root);
}
root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.left.left = new Node(70);
root.left.right = new Node(50);
root.right.left = new Node(60);
root.left.left.right = new Node(80);
preorderIterative();
</script>
|
Output10 20 40 70 80 50 30 60
Time Complexity: O(N)
Auxiliary Space: O(H), where H is the height of the tree.
ANOTHER APPROACH:
Intuition:
Using Morris Traversal, we can traverse the tree without using stack and recursion. The algorithm for Preorder is almost similar to Morris traversal for Inorder.
1…If left child is null, print the current node data. Move to right child.
….Else, Make the right child of the inorder predecessor point to the current node. Two cases arise:
………a) The right child of the inorder predecessor already points to the current node. Set right child to NULL. Move to right child of current node.
………b) The right child is NULL. Set it to the current node. Print the current node’s data and move to left child of current node.
2…Iterate until the current node is not NULL.
Implementation:
Java
class Node {
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree {
Node root;
void morrisTraversalPreorder()
{
morrisTraversalPreorder(root);
}
void morrisTraversalPreorder(Node node)
{
while (node != null ) {
if (node.left == null ) {
System.out.print(node.data + " " );
node = node.right;
}
else {
Node current = node.left;
while (current.right != null
&& current.right != node) {
current = current.right;
}
if (current.right == node) {
current.right = null ;
node = node.right;
}
else {
System.out.print(node.data + " " );
current.right = node;
node = node.left;
}
}
}
}
void preorder() { preorder(root); }
void preorder(Node node)
{
if (node != null ) {
System.out.print(node.data + " " );
preorder(node.left);
preorder(node.right);
}
}
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 1 );
tree.root.left = new Node( 2 );
tree.root.right = new Node( 3 );
tree.root.left.left = new Node( 4 );
tree.root.left.right = new Node( 5 );
tree.root.right.left = new Node( 6 );
tree.root.right.right = new Node( 7 );
tree.root.left.left.left = new Node( 8 );
tree.root.left.left.right = new Node( 9 );
tree.root.left.right.left = new Node( 10 );
tree.root.left.right.right = new Node( 11 );
tree.morrisTraversalPreorder();
System.out.println( "" );
tree.preorder();
}
}
|
C#
using System;
class Node
{
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree
{
public Node root;
public void morrisTraversalPreorder()
{
morrisTraversalPreorder(root);
}
public void morrisTraversalPreorder(Node node)
{
while (node != null )
{
if (node.left == null )
{
Console.Write(node.data + " " );
node = node.right;
}
else
{
Node current = node.left;
while (current.right != null
&& current.right != node)
{
current = current.right;
}
if (current.right == node)
{
current.right = null ;
node = node.right;
}
else
{
Console.Write(node.data + " " );
current.right = node;
node = node.left;
}
}
}
}
public void Preorder()
{
Preorder(root);
}
public void Preorder(Node node)
{
if (node != null )
{
Console.Write(node.data + " " );
Preorder(node.left);
Preorder(node.right);
}
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
tree.root.right.left = new Node(6);
tree.root.right.right = new Node(7);
tree.root.left.left.left = new Node(8);
tree.root.left.left.right = new Node(9);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(11);
tree.morrisTraversalPreorder();
Console.WriteLine();
tree.Preorder();
}
}
|
Javascript
class Node {
constructor(item) {
this .data = item;
this .left = this .right = null ;
}
}
class BinaryTree {
constructor() {
this .root = null ;
}
morrisTraversalPreorder() {
this .morrisTraversalPreorderHelper( this .root);
}
morrisTraversalPreorderHelper(node) {
while (node) {
if (node.left === null ) {
process.stdout.write(node.data + " " );
node = node.right;
} else {
let current = node.left;
while (current.right !== null && current.right !== node) {
current = current.right;
}
if (current.right === node) {
current.right = null ;
node = node.right;
} else {
process.stdout.write(node.data + " " );
current.right = node;
node = node.left;
}
}
}
}
preorder() {
this .preorderHelper( this .root);
}
preorderHelper(node) {
if (node !== null ) {
process.stdout.write(node.data + " " );
this .preorderHelper(node.left);
this .preorderHelper(node.right);
}
}
}
const tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
tree.root.right.left = new Node(6);
tree.root.right.right = new Node(7);
tree.root.left.left.left = new Node(8);
tree.root.left.left.right = new Node(9);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(11);
tree.morrisTraversalPreorder();
console.log( "" );
tree.preorder();
|
Output1 2 4 8 9 5 10 11 3 6 7
1 2 4 8 9 5 10 11 3 6 7
Time Complexity: O(n), we visit every node at most once.
Auxiliary Space: O(1), we use a constant amount of space for variables and pointers.