We have seen different ways of performing postorder traversal on Binary Trees.
- Post Order Traversal.
- Iterative Postorder Traversal using Two Stacks.
- Iterative Postorder Traversal using One Stack.
Here is another way of performing the postorder traversal on a Binary Tree iteratively using a single stack.
Using Single Stack with Two Fields - O(n) Time and O(n) Space
Consider the Below Terminologies for an extra field in the stack.
0 - Left element
1 - Right element
2 - Node element
Following is the detailed algorithm:
Take a Stack and perform the below operations:
1) Insert a pair of the root node as (node, 0).
2) Pop the top element to get the pair
(Let a = node and b be the variable)
If b is equal to 0:
Push another pair as (node, 1) and
Push the left child as (node->left, 0)
Repeat Step 2
Else If b is equal to 1:
Push another pair as (node, 2) and
Push right child of node as (node->right, 0)
Repeat Step 2
Else If b is equal to 2:
Print(node->data)
3) Repeat the above steps while stack is not empty
Consider the Below Binary Tree with just 3 nodes:

Illustration:
1) Push(a, 0)
Stack - (a, 0)
2) top = (a, 0)
Push(a, 1)
Push(b, 0)
Stack - (b, 0)
(a, 1)
3) top = (b, 0)
Push(b, 1)
Stack - (b, 1)
(a, 1)
4) top = (b, 1)
Push(b, 2)
Stack - (b, 2)
(a, 1)
5) top = (b, 2)
print(b)
Stack -(a, 1)
6) top = (a, 1)
push(a, 2)
push(c, 0)
Stack - (c, 0)
(a, 2)
7) top = (c, 0)
push(c, 1)
Stack - (c, 1)
(a, 2)
8) top = (c, 1)
push(c, 2)
Stack - (c, 2)
(a, 2)
9) top = (c, 2)
print(c)
Stack - (a, 2)
10) top = (a, 2)
print(a)
Stack - empty()
Below is the implementation of the above approach:
// C++ program for iterative postorder traversal
// using one stack with states
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int x) {
data = x;
left = right = nullptr;
}
};
// Function for iterative post-order traversal
// using a single stack
vector<int> postOrder(Node* root) {
vector<int> result;
if (root == nullptr) {
return result;
}
// Stack to store pairs of (Node, state)
stack<pair<Node*, int>> stk;
stk.push({root, 0});
while (!stk.empty()) {
// Get the top element of the stack
pair<Node*, int>& topElement = stk.top();
Node* node = topElement.first;
int& state = topElement.second;
if (state == 0) {
// State 0: Push left child and move to it
stk.top().second = 1;
if (node->left) {
stk.push({node->left, 0});
}
} else if (state == 1) {
// State 1: Push right child and move to it
stk.top().second = 2;
if (node->right) {
stk.push({node->right, 0});
}
} else {
// State 2: Process the node
result.push_back(node->data);
stk.pop();
}
}
return result;
}
void printArray(vector<int>& arr) {
for (int data : arr) {
cout << data << " ";
}
cout << endl;
}
int main() {
// Representation of input binary tree:
// 1
// / \
// 2 3
// / \
// 4 5
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->right->left = new Node(4);
root->right->right = new Node(5);
vector<int> result = postOrder(root);
printArray(result);
return 0;
}
// Java program for iterative postorder traversal
// using one stack with states
import java.util.*;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
public class GfG {
// Function for iterative post-order traversal
// using a single stack
public static ArrayList<Integer> postOrder(Node root) {
ArrayList<Integer> result = new ArrayList<>();
if (root == null) {
return result;
}
// Stack to store pairs of (Node, state)
Stack<Pair> stk = new Stack<>();
stk.push(new Pair(root, 0));
while (!stk.isEmpty()) {
// Get the top element of the stack
Pair topElement = stk.peek();
Node node = topElement.node;
int state = topElement.state;
if (state == 0) {
// State 0: Push left child and move to it
stk.peek().state = 1;
if (node.left != null) {
stk.push(new Pair(node.left, 0));
}
}
else if (state == 1) {
// State 1: Push right child and move to it
stk.peek().state = 2;
if (node.right != null) {
stk.push(new Pair(node.right, 0));
}
}
else {
// State 2: Process the node
result.add(node.data);
stk.pop();
}
}
return result;
}
static class Pair {
Node node;
int state;
Pair(Node node, int state) {
this.node = node;
this.state = state;
}
}
public static void printList(List<Integer> arr) {
for (int data : arr) {
System.out.print(data + " ");
}
System.out.println();
}
public static void main(String[] args) {
// Representation of input binary tree:
// 1
// / \
// 2 3
// / \
// 4 5
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.right.left = new Node(4);
root.right.right = new Node(5);
List<Integer> result = postOrder(root);
printList(result);
}
}
# Python program for iterative postorder traversal
# using one stack with states
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Function for iterative post-order traversal
# using a single stack
def postOrder(root):
result = []
if root is None:
return result
# Stack to store tuples of (Node, state)
stk = []
stk.append((root, 0))
while stk:
# Get the top element of the stack
node, state = stk[-1]
if state == 0:
# State 0: Push left child and move to it
stk[-1] = (node, 1)
if node.left:
stk.append((node.left, 0))
elif state == 1:
# State 1: Push right child and move to it
stk[-1] = (node, 2)
if node.right:
stk.append((node.right, 0))
else:
# State 2: Process the node
result.append(node.data)
stk.pop()
return result
def printList(arr):
print(" ".join(map(str, arr)))
if __name__ == "__main__":
# Representation of input binary tree:
# 1
# / \
# 2 3
# / \
# 4 5
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.right.left = Node(4)
root.right.right = Node(5)
result = postOrder(root)
printList(result)
// C# program for iterative postorder traversal
// using one stack with states
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Function for iterative post-order
// traversal using a single stack
public static List<int> PostOrder(Node root) {
List<int> result = new List<int>();
if (root == null) {
return result;
}
// Stack to store tuples of (Node, state)
Stack<(Node, int)> stk = new Stack<(Node, int)>();
stk.Push((root, 0));
while (stk.Count > 0) {
// Get the top element of the stack
var (node, state) = stk.Peek();
if (state == 0) {
// State 0: Push left child and move to it
stk.Pop();
stk.Push((node, 1));
if (node.left != null) {
stk.Push((node.left, 0));
}
}
else if (state == 1) {
// State 1: Push right child and move to it
stk.Pop();
stk.Push((node, 2));
if (node.right != null) {
stk.Push((node.right, 0));
}
}
else {
// State 2: Process the node
result.Add(node.data);
stk.Pop();
}
}
return result;
}
public static void PrintList(List<int> arr) {
foreach (int data in arr) {
Console.Write(data + " ");
}
Console.WriteLine();
}
static void Main() {
// Representation of input binary tree:
// 1
// / \
// 2 3
// / \
// 4 5
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.right.left = new Node(4);
root.right.right = new Node(5);
List<int> result = PostOrder(root);
PrintList(result);
}
}
// JavaScript program for iterative postorder traversal
// using one stack with states (using tuple-like array)
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
// Function for iterative post-order traversal
// using a single stack
function postOrder(root) {
let result = [];
if (root === null) {
return result;
}
// Stack to store tuples of [Node, state]
let stk = [];
stk.push([root, 0]);
while (stk.length > 0) {
// Get the top element of the stack
let [node, state] = stk[stk.length - 1];
if (state === 0) {
// State 0: Push left child and move to it
stk[stk.length - 1][1] = 1;
if (node.left !== null) {
stk.push([node.left, 0]);
}
}
else if (state === 1) {
// State 1: Push right child and move to it
stk[stk.length - 1][1] = 2;
if (node.right !== null) {
stk.push([node.right, 0]);
}
}
else {
// State 2: Process the node
result.push(node.data);
stk.pop();
}
}
return result;
}
// Helper function to print the result list
function printList(arr) {
console.log(arr.join(' '));
}
// Representation of input binary tree:
// 1
// / \
// 2 3
// / \
// 4 5
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.right.left = new Node(4);
root.right.right = new Node(5);
let result = postOrder(root);
printList(result);
Output
4 5 2 3 1
Time Complexity: O(n), since each node is visited exactly once, where n is the number of nodes in the tree.
Auxiliary Space: O(n), due to the stack storing tuple for each node, where n is the number of nodes in the tree.