Inorder Tree Traversal without Recursion
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 5Initially 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 <stdio.h> #include <stdlib.h> #define bool int // A binary tree tNode has data, pointer to left child // and a pointer to right child struct tNode { int data; struct tNode* left; struct tNode* right; }; // Structure of a stack node. Linked List implementation is // used for stack. A stack node contains a pointer to tree // node and a pointer to next stack node struct sNode { struct tNode* t; struct sNode* next; }; // Stack related functions void push( struct sNode** top_ref, struct tNode* t); struct tNode* pop( struct sNode** top_ref); bool isEmpty( struct sNode* top); // Iterative function for inorder tree traversal void inOrder( struct tNode* root) { // Set current to root of binary tree struct tNode* current = root; // Initialize stack s struct sNode* s = NULL; bool done = 0; while (!done) { // Reach the left most tNode of the current tNode if (current != NULL) { // Place pointer to a tree node on the stack // before traversing the node's left subtree push(&s, current); current = current->left; } // Backtrack from the empty subtree and visit the // tNode at the top of the stack; however, if the // stack is empty, you are done else { if (!isEmpty(s)) { current = pop(&s); printf ( "%d " , current->data); // we have visited the node and its left // subtree. Now, it's right subtree's turn current = current->right; } else done = 1; } } } // Function to push an item to sNode void push( struct sNode** top_ref, struct tNode* t) { // Allocate tNode struct sNode* new_tNode = ( struct sNode*) malloc ( sizeof ( struct sNode)); if (new_tNode == NULL) { printf ( "Stack Overflow \n" ); getchar (); exit (0); } // Put in the data new_tNode->t = t; // Link the old list of the new tNode new_tNode->next = (*top_ref); // Move the head to point to the new tNode (*top_ref) = new_tNode; } // The function returns true if stack is empty, // otherwise false bool isEmpty( struct sNode* top) { return (top == NULL) ? 1 : 0; } // Function to pop an item from stack struct tNode* pop( struct sNode** top_ref) { struct tNode* res; struct sNode* top; // If sNode is empty then error 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; } } // Helper function that allocates a new tNode with the // given data and NULL left and right pointers. 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); } // Driver program to test above functions int main() { /* Constructed binary tree is 1 / \ 2 3 / \ 4 5 */ 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; } |
C++
// C++ program to print inorder traversal // using stack. #include <bits/stdc++.h> using namespace std; // A binary tree Node has data, pointer to left child // and a pointer to right child struct Node { int data; struct Node* left; struct Node* right; Node( int data) { this ->data = data; left = right = NULL; } }; //Iterative function for inorder tree traversal void inOrder( struct Node* root) { stack<Node*> s; Node* curr = root; while (curr != NULL || s.empty() == false ) { // Reach the left most Node of the // curr Node while (curr != NULL) { // Place pointer to a tree node on // the stack before traversing // the node's left subtree s.push(curr); curr = curr->left; } // Current must be NULL at this point curr = s.top(); s.pop(); cout << curr->data << " " ; // we have visited the node and its // left subtree. Now, it's right // subtree's turn curr = curr->right; } } // Driver program to test above functions int main() { /* Constructed binary tree is 1 / \ 2 3 / \ 4 5 */ 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; } |
Java
// Non-recursive java program for inorder traversal import java.util.Stack; // Class containing left and right child of // current node and key value class Node { int data; Node left, right; public Node( int item) { data = item; left = right = null ; } } // Class to print the inorder traversal class BinaryTree { Node root; void inorder() { if (root == null ) return ; Stack<Node> s = new Stack<Node>(); Node curr = root; // Traverse the tree while (curr != null || s.size() > 0 ) { // Reach the left most Node of the // curr Node while (curr != null ) { // Place pointer to a tree node on // the stack before traversing // the node's left subtree s.push(curr); curr = curr.left; } // Current must be NULL at this point curr = s.pop(); System.out.print(curr.data + " " ); // we have visited the node and its // left subtree. Now, it's right // subtree's turn curr = curr.right; } } public static void main(String args[]) { // Creating a binary tree and entering // the nodes 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
# Python program to do inorder traversal without recursion # A binary tree node class Node: # Constructor to create a new node def __init__( self , data): self .data = data self .left = None self .right = None # Iterative function for inorder tree traversal def inOrder(root): # Set current to root of binary tree current = root # Initialize stack stack = [] while True : # Reach the left most Node of the current Node if current is not None : # Place pointer to a tree node on the stack # before traversing the node's left subtree stack.append(current) current = current.left # BackTrack from the empty subtree and visit the Node # at the top of the stack; however, if the stack is # empty you are done elif (stack): current = stack.pop() print (current.data, end = " " ) # We have visited the node and its left # subtree. Now, it's right subtree's turn current = current.right else : break print () # Driver program to test above function if __name__ = = '__main__' : """ Constructed binary tree is 1 / \ 2 3 / \ 4 5 """ root = Node( 1 ) root.left = Node( 2 ) root.right = Node( 3 ) root.left.left = Node( 4 ) root.left.right = Node( 5 ) inOrder(root) # This code is contributed by Nikhil Kumar Singh(nickzuck_007) |
C#
// Non-recursive C# program for inorder traversal using System; using System.Collections.Generic; // Class containing left and right child of // current node and key value public class Node { public int data; public Node left, right; public Node( int item) { data = item; left = right = null ; } } // Class to print the inorder traversal public class BinaryTree { public Node root; public virtual void inorder() { if (root == null ) { return ; } Stack<Node> s = new Stack<Node>(); Node curr = root; // Traverse the tree while (curr != null || s.Count > 0) { // Reach the left most Node of the // curr Node while (curr != null ) { // Place pointer to a tree node on // the stack before traversing // the node's left subtree s.Push(curr); curr = curr.left; } // Current must be NULL at this point curr = s.Pop(); Console.Write(curr.data + " " ); // we have visited the node and its // left subtree. Now, it's right // subtree's turn curr = curr.right; } } public static void Main( string [] args) { // Creating a binary tree and entering // the nodes 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(); } } // This code is contributed by Shrikant13 |
Javascript
// Non-recursive javascript program for inorder traversal // Class containing left and right child of // current node and key value class Node { constructor(item) { this .data = item; this .left = this .right = null ; } } // Class to print the inorder traversal var root; function inorder() { if (root == null ) return ; var s = []; var curr = root; // traverse the tree while (curr != null || s.length > 0) { // Reach the left most Node of the curr Node while (curr != null ) { // Place pointer to a tree node on the stack // before traversing the node's left subtree s.push(curr); curr = curr.left; } // Current must be NULL at this point curr = s.pop(); console.log(curr.data + " " ); // We have visited the node and its left subtree. // Now, it's right subtree's turn curr = curr.right; } } // Creating a binary tree and entering the nodes 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(); // This code is contributed by umadevi9616 |
4 2 5 1 3
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++
// C++ program for Inorder Morris Traversal #include <bits/stdc++.h> using namespace std; // A binary tree tNode has data, a pointer to left child // and a pointer to right child struct tNode { int data; struct tNode* left; struct tNode* right; }; // Function to traverse the binary tree // without recursion and without stack 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 { // Find the inorder predecessor of current pre = current->left; while (pre->right != NULL && pre->right != current) pre = pre->right; // Make current as the right child of its // inorder predecessor if (pre->right == NULL) { pre->right = current; current = current->left; } // Revert the changes made in the 'if' part to // restore the original tree i.e., fix the right // child of predecessor 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); } // Driver code 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; } // This code is contributed by Raunak Singh |
Java
// Java program for Inorder Morris Traversal 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; } } } } // Driver code 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(); } } // This code is contributed by Raunak Singh |
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 : # Find the inorder predecessor of current pre = current.left while pre.right and pre.right ! = current: pre = pre.right # Make current as the right child of its inorder predecessor if pre.right is None : pre.right = current current = current.left # Revert the changes made to restore the original tree and print current node else : pre.right = None print (current.data, end = " " ) current = current.right # Driver program to test above functions if __name__ = = '__main__' : """ Constructed binary tree is 1 / \ 2 3 / \ 4 5 """ 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#
// C# program for Inorder Morris Traversal using System; // A binary tree tNode has data, a pointer to left child // and a pointer to right child class Node { public int data; public Node left, right; public Node( int item) { data = item; left = right = null ; } } class GFG { public Node root; // Function to traverse the binary tree without // recursion and without stack public void inOrder() { Node cur = root; while (cur != null ) { if (cur.left == null ) { Console.Write(cur.data + " " ); cur = cur.right; } else { // Find the inorder predecessor of current Node temp = cur.left; while (temp.right != null && temp.right != cur) temp = temp.right; // Make current as the right child of its // inorder predecessor if (temp.right == null ) { temp.right = cur; cur = cur.left; } // Revert the changes made in the 'if' part // to restore the original tree i.e., fix // the right child of predecessor else { temp.right = null ; Console.Write(cur.data + " " ); cur = cur.right; } } } } // Driver code 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(); } } |
4 2 5 1 3
Time Complexity: O(N), where N is the number of nodes in a tree.
Auxiliary Space: O(1)
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...