Inorder Tree Traversal without Recursion
Last Updated :
02 Oct, 2023
In this post, we have seen in detail about the Inorder traversal and how it is implemented using recursion.
Here in this post, we will discuss methods to implement inorder traversal without using recursion.
Inorder Traversal using Stack:
As we already know, recursion can also be implemented using stack. Here also we can use a stack to perform inorder traversal of a Binary Tree. Below is the algorithm for traversing a binary tree using stack.
- Create an empty stack (say S).
- Initialize the current node as root.
- Push the current node to S and set current = current->left until current is NULL
- If current is NULL and the stack is not empty then:
- Pop the top item from the stack.
- Print the popped item and set current = popped_item->right
- Go to step 3.
- If current is NULL and the stack is empty then we are done.
Illustration:
See the below illustration for a better understanding.
Let us consider the below tree for example
1
/ \
2 3
/ \
4 5
Initially Creates an empty stack: S = NULL and set current as address of root: current -> 1
current = 1: Pushes the current node and set current = current->left until current is NULL:
- current -> 1, push 1: Stack S -> 1
- current -> 2, push 2: Stack S -> 2, 1
- current -> 4, push 4: Stack S -> 4, 2, 1
- current = NULL
Now Pop from S
- Pop 4: Stack S -> 2, 1. Print “4”.
- current = NULL /*right of 4 */ and go to step 3. Since current is NULL step 3 doesn’t do anything.
Step 4 is repeated and pop again.
- Pop 2: Stack S -> 1. Print “2”.
- current -> 5 /*right of 2 */ and go to step 3
current = 5: Push 5 to stack and make current = current->left which is NULL
- Stack S -> 5, 1. current = NULL
Now pop from S
- Pop 5: Stack S -> 1. Print “5”.
- current = NULL /*right of 5 */ and go to step 3. Since current is NULL step 3 doesn’t do anything
Step 4 repeated again:
- Pop 1: Stack S -> NULL. Print “1”.
- current -> 3 /*right of 1 */
current = 3: Pushes 3 to stack and make current NULL
- Stack S -> 3
- current = NULL
Step 4 pops from S:
- Pop 3: Stack S -> NULL. Print “3”.
- current = NULL /*right of 3 */
Now the traversal is complete as the stack has become empty.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* left;
struct Node* right;
Node( int data)
{
this ->data = data;
left = right = NULL;
}
};
void inOrder( struct Node* root)
{
stack<Node*> s;
Node* curr = root;
while (curr != NULL || s.empty() == false ) {
while (curr != NULL) {
s.push(curr);
curr = curr->left;
}
curr = s.top();
s.pop();
cout << curr->data << " " ;
curr = curr->right;
}
}
int main()
{
struct Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
inOrder(root);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
#define bool int
struct tNode {
int data;
struct tNode* left;
struct tNode* right;
};
struct sNode {
struct tNode* t;
struct sNode* next;
};
void push( struct sNode** top_ref, struct tNode* t);
struct tNode* pop( struct sNode** top_ref);
bool isEmpty( struct sNode* top);
void inOrder( struct tNode* root)
{
struct tNode* current = root;
struct sNode* s = NULL;
bool done = 0;
while (!done) {
if (current != NULL) {
push(&s, current);
current = current->left;
}
else {
if (!isEmpty(s)) {
current = pop(&s);
printf ( "%d " , current->data);
current = current->right;
}
else
done = 1;
}
}
}
void push( struct sNode** top_ref, struct tNode* t)
{
struct sNode* new_tNode
= ( struct sNode*) malloc ( sizeof ( struct sNode));
if (new_tNode == NULL) {
printf ( "Stack Overflow \n" );
getchar ();
exit (0);
}
new_tNode->t = t;
new_tNode->next = (*top_ref);
(*top_ref) = new_tNode;
}
bool isEmpty( struct sNode* top)
{
return (top == NULL) ? 1 : 0;
}
struct tNode* pop( struct sNode** top_ref)
{
struct tNode* res;
struct sNode* top;
if (isEmpty(*top_ref)) {
printf ( "Stack Underflow \n" );
getchar ();
exit (0);
}
else {
top = *top_ref;
res = top->t;
*top_ref = top->next;
free (top);
return res;
}
}
struct tNode* newtNode( int data)
{
struct tNode* tNode
= ( struct tNode*) malloc ( sizeof ( struct tNode));
tNode->data = data;
tNode->left = NULL;
tNode->right = NULL;
return (tNode);
}
int main()
{
struct tNode* root = newtNode(1);
root->left = newtNode(2);
root->right = newtNode(3);
root->left->left = newtNode(4);
root->left->right = newtNode(5);
inOrder(root);
getchar ();
return 0;
}
|
Java
import java.util.Stack;
class Node
{
int data;
Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree
{
Node root;
void inorder()
{
if (root == null )
return ;
Stack<Node> s = new Stack<Node>();
Node curr = root;
while (curr != null || s.size() > 0 )
{
while (curr != null )
{
s.push(curr);
curr = curr.left;
}
curr = s.pop();
System.out.print(curr.data + " " );
curr = curr.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.inorder();
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def inOrder(root):
current = root
stack = []
while True :
if current is not None :
stack.append(current)
current = current.left
elif (stack):
current = stack.pop()
print (current.data, end = " " )
current = current.right
else :
break
print ()
if __name__ = = '__main__' :
root = Node( 1 )
root.left = Node( 2 )
root.right = Node( 3 )
root.left.left = Node( 4 )
root.left.right = Node( 5 )
inOrder(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 {
public Node root;
public virtual void inorder()
{
if (root == null ) {
return ;
}
Stack<Node> s = new Stack<Node>();
Node curr = root;
while (curr != null || s.Count > 0) {
while (curr != null ) {
s.Push(curr);
curr = curr.left;
}
curr = s.Pop();
Console.Write(curr.data + " " );
curr = curr.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.inorder();
}
}
|
Javascript
class Node {
constructor(item) {
this .data = item;
this .left = this .right = null ;
}
}
var root;
function inorder()
{
if (root == null )
return ;
var s = [];
var curr = root;
while (curr != null || s.length > 0)
{
while (curr != null )
{
s.push(curr);
curr = curr.left;
}
curr = s.pop();
console.log(curr.data + " " );
curr = curr.right;
}
}
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
inorder();
|
Time Complexity: O(N) where N is the number of nodes in the tree
Auxiliary Space: O(N)
Inorder traversal using Morris Traversal:
Following is the algorithm to implement inorder traversal using Morris traversal:
- Initialize the current node as root.
- While current is not null, check if it has a left child.
- If there is no left child, print the current node and move to the right child of the current node.
- Otherwise, find the rightmost node of the left subtree or the node whose right child is the current node:
- If the right child is NULL, make current as the right child and move to the left child of current.
- If the right child is the current node itself, print current node, make the right child NULL and move to the right child of the current node.
Below is the implementation of the above approach
C++
#include <bits/stdc++.h>
using namespace std;
struct tNode {
int data;
struct tNode* left;
struct tNode* right;
};
void inOrder( struct tNode* root)
{
struct tNode *current, *pre;
if (root == NULL)
return ;
current = root;
while (current != NULL) {
if (current->left == NULL) {
cout << current->data << " " ;
current = current->right;
}
else {
pre = current->left;
while (pre->right != NULL
&& pre->right != current)
pre = pre->right;
if (pre->right == NULL) {
pre->right = current;
current = current->left;
}
else {
pre->right = NULL;
cout << current->data << " " ;
current = current->right;
}
}
}
}
struct tNode* newtNode( int data)
{
struct tNode* node = new tNode;
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
int main()
{
struct tNode* root = newtNode(1);
root->left = newtNode(2);
root->right = newtNode(3);
root->left->left = newtNode(4);
root->left->right = newtNode(5);
inOrder(root);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class Node {
int data;
Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
public class GFG {
Node root;
void inOrder()
{
Node cur = root;
while (cur != null ) {
if (cur.left == null ) {
System.out.print(cur.data + " " );
cur = cur.right;
}
else {
Node temp = cur.left;
while (temp.right != null
&& temp.right != cur)
temp = temp.right;
if (temp.right == null ) {
temp.right = cur;
cur = cur.left;
}
else {
temp.right = null ;
System.out.print(cur.data + " " );
cur = cur.right;
}
}
}
}
public static void main(String args[])
{
GFG tree = new GFG();
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.inOrder();
}
}
|
Python3
class TreeNode:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def morris_traversal(root):
current = root
while current:
if current.left is None :
print (current.data, end = " " )
current = current.right
else :
pre = current.left
while pre.right and pre.right ! = current:
pre = pre.right
if pre.right is None :
pre.right = current
current = current.left
else :
pre.right = None
print (current.data, end = " " )
current = current.right
if __name__ = = '__main__' :
root = TreeNode( 1 )
root.left = TreeNode( 2 )
root.right = TreeNode( 3 )
root.left.left = TreeNode( 4 )
root.left.right = TreeNode( 5 )
morris_traversal(root)
|
C#
using System;
class Node {
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class GFG {
public Node root;
public void inOrder()
{
Node cur = root;
while (cur != null ) {
if (cur.left == null ) {
Console.Write(cur.data + " " );
cur = cur.right;
}
else {
Node temp = cur.left;
while (temp.right != null
&& temp.right != cur)
temp = temp.right;
if (temp.right == null ) {
temp.right = cur;
cur = cur.left;
}
else {
temp.right = null ;
Console.Write(cur.data + " " );
cur = cur.right;
}
}
}
}
static void Main( string [] args)
{
GFG tree = new GFG();
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.inOrder();
}
}
|
Javascript
class TreeNode {
constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
function morrisTraversal(root) {
let current = root;
while (current) {
if (current.left === null ) {
console.log(current.data + " " );
current = current.right;
} else {
let pre = current.left;
while (pre.right && pre.right !== current) {
pre = pre.right;
}
if (pre.right === null ) {
pre.right = current;
current = current.left;
} else {
pre.right = null ;
console.log(current.data + " " );
current = current.right;
}
}
}
}
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
morrisTraversal(root);
|
Time Complexity: O(N), where N is the number of nodes in a tree.
Auxiliary Space: O(1)
Inorder Traversal using Iterative way
Below is the Implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct node {
int data;
struct node * left, * right;
};
vector < int > inOrderTrav(node * curr) {
vector < int > inOrder;
stack < node * > s;
while ( true ) {
if (curr != NULL) {
s.push(curr);
curr = curr -> left;
} else {
if (s.empty()) break ;
curr = s.top();
inOrder.push_back(curr -> data);
s.pop();
curr = curr -> right;
}
}
return inOrder;
}
struct node * newNode( int data) {
struct node * node = ( struct node * ) malloc ( sizeof ( struct node));
node -> data = data;
node -> left = NULL;
node -> right = NULL;
return (node);
}
int main() {
struct node * root = newNode(1);
root -> left = newNode(2);
root -> right = newNode(3);
root -> left -> left = newNode(4);
root -> left -> right = newNode(5);
root -> left -> right -> left = newNode(8);
root -> right -> left = newNode(6);
root -> right -> right = newNode(7);
root -> right -> right -> left = newNode(9);
root -> right -> right -> right = newNode(10);
vector < int > inOrder;
inOrder = inOrderTrav(root);
cout << "The inOrder Traversal is : " ;
for ( int i = 0; i < inOrder.size(); i++) {
cout << inOrder[i] << " " ;
}
return 0;
}
|
Java
import java.util.*;
class Node {
int data;
Node left, right;
Node( int data) {
this .data = data;
left = null ;
right = null ;
}
}
class gfg {
static ArrayList < Integer > inOrderTrav(Node curr) {
ArrayList < Integer > inOrder = new ArrayList < > ();
Stack < Node > s = new Stack < > ();
while ( true ) {
if (curr != null ) {
s.push(curr);
curr = curr.left;
} else {
if (s.isEmpty()) break ;
curr = s.peek();
inOrder.add(curr.data);
s.pop();
curr = curr.right;
}
}
return inOrder;
}
public static void main(String args[]) {
Node root = new Node( 1 );
root.left = new Node( 2 );
root.right = new Node( 3 );
root.left.left = new Node( 4 );
root.left.right = new Node( 5 );
root.left.right.left = new Node( 8 );
root.right.left = new Node( 6 );
root.right.right = new Node( 7 );
root.right.right.left = new Node( 9 );
root.right.right.right = new Node( 10 );
ArrayList < Integer > inOrder;
inOrder = inOrderTrav(root);
System.out.println( "The inOrder Traversal is : " );
for ( int i = 0 ; i < inOrder.size(); i++) {
System.out.print(inOrder.get(i) + " " );
}
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def inOrderTrav(curr):
inOrder = []
s = []
while True :
if curr:
s.append(curr)
curr = curr.left
else :
if not s:
break
curr = s[ - 1 ]
inOrder.append(curr.data)
s.pop()
curr = curr.right
return inOrder
if __name__ = = "__main__" :
root = Node( 1 )
root.left = Node( 2 )
root.right = Node( 3 )
root.left.left = Node( 4 )
root.left.right = Node( 5 )
root.left.right.left = Node( 8 )
root.right.left = Node( 6 )
root.right.right = Node( 7 )
root.right.right.left = Node( 9 )
root.right.right.right = Node( 10 )
inOrder = inOrderTrav(root)
print ( "The inOrder Traversal is : " )
for data in inOrder:
print (data, end = " " )
|
C#
using System;
using System.Collections.Generic;
public class Node
{
public int data;
public Node left;
public Node right;
}
public class InOrderTraversal
{
public static List< int > InOrderTrav(Node curr)
{
List< int > inOrder = new List< int >();
Stack<Node> stack = new Stack<Node>();
while ( true )
{
if (curr != null )
{
stack.Push(curr);
curr = curr.left;
}
else
{
if (stack.Count == 0)
break ;
curr = stack.Pop();
inOrder.Add(curr.data);
curr = curr.right;
}
}
return inOrder;
}
public static Node NewNode( int data)
{
Node node = new Node();
node.data = data;
node.left = null ;
node.right = null ;
return node;
}
public static void Main()
{
Node root = NewNode(1);
root.left = NewNode(2);
root.right = NewNode(3);
root.left.left = NewNode(4);
root.left.right = NewNode(5);
root.left.right.left = NewNode(8);
root.right.left = NewNode(6);
root.right.right = NewNode(7);
root.right.right.left = NewNode(9);
root.right.right.right = NewNode(10);
List< int > inOrder = new List< int >();
inOrder = InOrderTrav(root);
Console.Write( "The inOrder Traversal is : " );
foreach ( int val in inOrder)
{
Console.Write(val + " " );
}
}
}
|
Javascript
class Node {
constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
function inOrderTrav(curr) {
const inOrder = [];
const stack = [];
while ( true ) {
if (curr !== null ) {
stack.push(curr);
curr = curr.left;
} else {
if (stack.length === 0)
break ;
curr = stack.pop();
inOrder.push(curr.data);
curr = curr.right;
}
}
return inOrder;
}
function newNode(data) {
const node = new Node(data);
return node;
}
const root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(4);
root.left.right = newNode(5);
root.left.right.left = newNode(8);
root.right.left = newNode(6);
root.right.right = newNode(7);
root.right.right.left = newNode(9);
root.right.right.right = newNode(10);
const inOrder = inOrderTrav(root);
console.log( "The inOrder Traversal is: " + inOrder.join( " " ));
|
Output
The inOrder Traversal is : 4 2 8 5 1 6 3 9 7 10
Time Complexity : O(N)
Auxiliary Space : O(N)
See this post for another approach of Inorder Tree Traversal without recursion and without stack!
Please write comments if you find any bug in above code/algorithm, or want to share more information about stack based Inorder Tree Traversal.
Please Login to comment...