Last Updated : 31 Mar, 2023
Given a binary tree, perform postorder traversal.
Prerequisite - Inorder/preorder/postorder traversal of tree
We have discussed the below methods for postorder traversal.
1) Recursive Postorder Traversal.
2) Postorder traversal using Stack.
2) Postorder traversal using two Stacks.
Approach 1
The approach used is based on using an unordered set to keep track of visited nodes and a while loop to traverse the tree. The steps involved in the approach can be expressed mathematically as follows:
Algorithm
Define a struct Node with integer data, pointer to left child and pointer to right child. Define a helper function called "postorder" which takes a pointer to the head of the tree. Create a pointer "temp" and an unordered set "visited". While "temp" is not NULL and "temp" is not visited before: a. If "temp" has a left child and the left child is not visited before, then set "temp" to its left child and continue the loop. b. If "temp" does not have a left child or the left child is already visited, check if "temp" has a right child and the right child is not visited before. If yes, set "temp" to its right child and continue the loop. c. If "temp" does not have a left child or the left child is already visited, and "temp" does not have a right child or the right child is already visited, then print the data of "temp", insert "temp" into "visited" set, and set "temp" to the head of the tree. Define a function called "newNode" which takes an integer data as input and returns a new Node with the given data, NULL left pointer, and NULL right pointer.C++
// CPP program or postorder traversal
#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, *right;
};
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
void postorder(struct Node* head)
{
struct Node* temp = head;
unordered_set<Node*> visited;
while (temp && visited.find(temp) == visited.end()) {
// Visited left subtree
if (temp->left &&
visited.find(temp->left) == visited.end())
temp = temp->left;
// Visited right subtree
else if (temp->right &&
visited.find(temp->right) == visited.end())
temp = temp->right;
// Print node
else {
printf("%d ", temp->data);
visited.insert(temp);
temp = head;
}
}
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
/* Driver program to test above functions*/
int main()
{
struct Node* root = newNode(8);
root->left = newNode(3);
root->right = newNode(10);
root->left->left = newNode(1);
root->left->right = newNode(6);
root->left->right->left = newNode(4);
root->left->right->right = newNode(7);
root->right->right = newNode(14);
root->right->right->left = newNode(13);
postorder(root);
return 0;
}
Java
// JAVA program or postorder traversal
import java.util.*;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class Node
{
int data;
Node left, right;
Node(int data)
{
this.data = data;
this.left = this.right = null;
}
};
class GFG
{
Node root;
/* Helper function that allocates a new node with the
given data and null left and right pointers. */
void postorder(Node head)
{
Node temp = root;
HashSet<Node> visited = new HashSet<>();
while ((temp != null && !visited.contains(temp)))
{
// Visited left subtree
if (temp.left != null &&
!visited.contains(temp.left))
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
!visited.contains(temp.right))
temp = temp.right;
// Print node
else
{
System.out.printf("%d ", temp.data);
visited.add(temp);
temp = head;
}
}
}
/* Driver program to test above functions*/
public static void main(String[] args)
{
GFG gfg = new GFG();
gfg.root = new Node(8);
gfg.root.left = new Node(3);
gfg.root.right = new Node(10);
gfg.root.left.left = new Node(1);
gfg.root.left.right = new Node(6);
gfg.root.left.right.left = new Node(4);
gfg.root.left.right.right = new Node(7);
gfg.root.right.right = new Node(14);
gfg.root.right.right.left = new Node(13);
gfg.postorder(gfg.root);
}
}
// This code is contributed by Rajput-Ji
Python
# Python program or postorder traversal
''' A binary tree node has data, pointer to left child
and a pointer to right child '''
class newNode:
# Constructor to create a newNode
def __init__(self, data):
self.data = data
self.left = None
self.right = None
''' Helper function that allocates a new node with the
given data and NULL left and right pointers. '''
def postorder(head):
temp = head
visited = set()
while (temp and temp not in visited):
# Visited left subtree
if (temp.left and temp.left not in visited):
temp = temp.left
# Visited right subtree
elif (temp.right and temp.right not in visited):
temp = temp.right
# Print node
else:
print(temp.data, end = " ")
visited.add(temp)
temp = head
''' Driver program to test above functions'''
if __name__ == '__main__':
root = newNode(8)
root.left = newNode(3)
root.right = newNode(10)
root.left.left = newNode(1)
root.left.right = newNode(6)
root.left.right.left = newNode(4)
root.left.right.right = newNode(7)
root.right.right = newNode(14)
root.right.right.left = newNode(13)
postorder(root)
# This code is contributed by
# SHUBHAMSINGH10
C#
// C# program or postorder traversal
using System;
using System.Collections.Generic;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
public
class Node
{
public
int data;
public
Node left, right;
public
Node(int data)
{
this.data = data;
this.left = this.right = null;
}
};
class GFG
{
Node root;
/* Helper function that allocates a new node with the
given data and null left and right pointers. */
void postorder(Node head)
{
Node temp = root;
HashSet<Node> visited = new HashSet<Node>();
while ((temp != null && !visited.Contains(temp)))
{
// Visited left subtree
if (temp.left != null &&
!visited.Contains(temp.left))
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
!visited.Contains(temp.right))
temp = temp.right;
// Print node
else
{
Console.Write(temp.data + " ");
visited.Add(temp);
temp = head;
}
}
}
/* Driver code*/
public static void Main(String[] args)
{
GFG gfg = new GFG();
gfg.root = new Node(8);
gfg.root.left = new Node(3);
gfg.root.right = new Node(10);
gfg.root.left.left = new Node(1);
gfg.root.left.right = new Node(6);
gfg.root.left.right.left = new Node(4);
gfg.root.left.right.right = new Node(7);
gfg.root.right.right = new Node(14);
gfg.root.right.right.left = new Node(13);
gfg.postorder(gfg.root);
}
}
// This code is contributed by Rajput-Ji
JavaScript
<script>
// JavaScript program or postorder traversal
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class Node
{
constructor(data)
{
this.data = data;
this.left = null;
this.right = null;
}
};
var root = null;
/* Helper function that allocates a new node with the
given data and null left and right pointers. */
function postorder(head)
{
var temp = root;
var visited = new Set();
while ((temp != null && !visited.has(temp)))
{
// Visited left subtree
if (temp.left != null &&
!visited.has(temp.left))
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
!visited.has(temp.right))
temp = temp.right;
// Print node
else
{
document.write(temp.data + " ");
visited.add(temp);
temp = head;
}
}
}
/* Driver code*/
root = new Node(8);
root.left = new Node(3);
root.right = new Node(10);
root.left.left = new Node(1);
root.left.right = new Node(6);
root.left.right.left = new Node(4);
root.left.right.right = new Node(7);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
postorder(root);
</script>
Output:
1 4 7 6 3 13 14 10 8
Time complexity: O(N) where N is no of nodes in a binary tree
Auxiliary Space: O(n) since using unordered_set
Alternate Solution:We can keep the visited flag with every node instead of a separate hash table.
C++
// CPP program or postorder traversal
#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, *right;
bool visited;
};
void postorder(struct Node* head)
{
struct Node* temp = head;
while (temp && temp->visited == false) {
// Visited left subtree
if (temp->left && temp->left->visited == false)
temp = temp->left;
// Visited right subtree
else if (temp->right && temp->right->visited == false)
temp = temp->right;
// Print node
else {
printf("%d ", temp->data);
temp->visited = true;
temp = head;
}
}
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = NULL;
node->right = NULL;
node->visited = false;
return (node);
}
/* Driver program to test above functions*/
int main()
{
struct Node* root = newNode(8);
root->left = newNode(3);
root->right = newNode(10);
root->left->left = newNode(1);
root->left->right = newNode(6);
root->left->right->left = newNode(4);
root->left->right->right = newNode(7);
root->right->right = newNode(14);
root->right->right->left = newNode(13);
postorder(root);
return 0;
}
Java
// Java program or postorder traversal
class GFG
{
/* A binary tree node has data,
pointer to left child
and a pointer to right child */
static class Node
{
int data;
Node left, right;
boolean visited;
}
static void postorder( Node head)
{
Node temp = head;
while (temp != null &&
temp.visited == false)
{
// Visited left subtree
if (temp.left != null &&
temp.left.visited == false)
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
temp.right.visited == false)
temp = temp.right;
// Print node
else
{
System.out.printf("%d ", temp.data);
temp.visited = true;
temp = head;
}
}
}
static Node newNode(int data)
{
Node node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return (node);
}
/* Driver code*/
public static void main(String []args)
{
Node root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
}
}
// This code is contributed by Arnab Kundu
Python3
"""Python3 program or postorder traversal """
# A Binary Tree Node
# Utility function to create a
# new tree node
class newNode:
# Constructor to create a newNode
def __init__(self, data):
self.data = data
self.left = None
self.right = None
self.visited = False
def postorder(head) :
temp = head
while (temp and temp.visited == False):
# Visited left subtree
if (temp.left and
temp.left.visited == False):
temp = temp.left
# Visited right subtree
elif (temp.right and
temp.right.visited == False):
temp = temp.right
# Print node
else:
print(temp.data, end = " ")
temp.visited = True
temp = head
# Driver Code
if __name__ == '__main__':
root = newNode(8)
root.left = newNode(3)
root.right = newNode(10)
root.left.left = newNode(1)
root.left.right = newNode(6)
root.left.right.left = newNode(4)
root.left.right.right = newNode(7)
root.right.right = newNode(14)
root.right.right.left = newNode(13)
postorder(root)
# This code is contributed by
# SHUBHAMSINGH10
C#
// C# program or postorder traversal
using System;
class GFG
{
/* A binary tree node has data,
pointer to left child
and a pointer to right child */
class Node
{
public int data;
public Node left, right;
public bool visited;
}
static void postorder( Node head)
{
Node temp = head;
while (temp != null &&
temp.visited == false)
{
// Visited left subtree
if (temp.left != null &&
temp.left.visited == false)
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
temp.right.visited == false)
temp = temp.right;
// Print node
else
{
Console.Write("{0} ", temp.data);
temp.visited = true;
temp = head;
}
}
}
static Node newNode(int data)
{
Node node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return (node);
}
/* Driver code*/
public static void Main(String []args)
{
Node root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
}
}
// This code is contributed by 29AjayKumar
JavaScript
<script>
// JavaScript program or postorder traversal
/* A binary tree node has data,
pointer to left child
and a pointer to right child */
class Node
{
constructor() {
this.data;
this.left;
this.right;
this.visited;
}
}
function postorder(head)
{
let temp = head;
while (temp != null &&
temp.visited == false)
{
// Visited left subtree
if (temp.left != null &&
temp.left.visited == false)
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
temp.right.visited == false)
temp = temp.right;
// Print node
else
{
document.write(temp.data + " ");
temp.visited = true;
temp = head;
}
}
}
function newNode(data)
{
let node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return (node);
}
let root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
</script>
Output:
1 4 7 6 3 13 14 10 8
Time complexity: O(n2) in worst case we move pointer back to head after visiting every node.
Auxiliary Space: O(1)
Alternate solution using unordered_map in which we do not have to move pointer back to head, so time complexity is O(n).
C++
// CPP program or postorder traversal
#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, *right;
bool visited;
};
void postorder(Node* root)
{
Node* n = root;
unordered_map<Node*, Node*> parentMap;
parentMap.insert(pair<Node*, Node*>(root, nullptr));
while (n) {
if (n->left && parentMap.find(n->left) == parentMap.end()) {
parentMap.insert(pair<Node*, Node*>(n->left, n));
n = n->left;
}
else if (n->right && parentMap.find(n->right) == parentMap.end()) {
parentMap.insert(pair<Node*, Node*>(n->right, n));
n = n->right;
}
else {
cout << n->data << " ";
n = (parentMap.find(n))->second;
}
}
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = NULL;
node->right = NULL;
node->visited = false;
return (node);
}
/* Driver program to test above functions*/
int main()
{
struct Node* root = newNode(8);
root->left = newNode(3);
root->right = newNode(10);
root->left->left = newNode(1);
root->left->right = newNode(6);
root->left->right->left = newNode(4);
root->left->right->right = newNode(7);
root->right->right = newNode(14);
root->right->right->left = newNode(13);
postorder(root);
return 0;
}
Java
import java.util.HashMap;
import java.util.Map;
class Node {
int data;
Node left, right;
boolean visited;
}
public class Tree {
static Map<Node, Node> parentMap = new HashMap<>();
static void postorder(Node root) {
Node n = root;
parentMap.put(root, null);
while (n != null) {
if (n.left != null && !parentMap.containsKey(n.left)) {
parentMap.put(n.left, n);
n = n.left;
} else if (n.right != null && !parentMap.containsKey(n.right)) {
parentMap.put(n.right, n);
n = n.right;
} else {
System.out.print(n.data + " ");
n = parentMap.get(n);
}
}
}
static Node newNode(int data) {
Node node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return node;
}
public static void main(String[] args) {
Node root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
}
}
Python3
# Python3 code for the above approach
# A binary tree node class
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
self.visited = False
def postorder(root):
n = root
parent_map = {}
parent_map[root] = None
while n:
if n.left and n.left not in parent_map:
parent_map[n.left] = n
n = n.left
elif n.right and n.right not in parent_map:
parent_map[n.right] = n
n = n.right
else:
print(n.data, end = " ")
n = parent_map[n]
# Driver code
if __name__ == '__main__':
root = Node(8)
root.left = Node(3)
root.right = Node(10)
root.left.left = Node(1)
root.left.right = Node(6)
root.left.right.left = Node(4)
root.left.right.right = Node(7)
root.right.right = Node(14)
root.right.right.left = Node(13)
postorder(root)
C#
// C# program or postorder traversal
using System;
using System.Collections.Generic;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class Node {
public int data;
public Node left, right;
public bool visited;
}
class Tree {
static Dictionary<Node, Node> parentMap = new Dictionary<Node, Node>();
static void postorder(Node root) {
Node n = root;
parentMap[root] = null;
while (n != null) {
if (n.left != null && !parentMap.ContainsKey(n.left)) {
parentMap[n.left] = n;
n = n.left;
} else if (n.right != null && !parentMap.ContainsKey(n.right)) {
parentMap[n.right] = n;
n = n.right;
} else {
Console.Write(n.data + " ");
n = parentMap[n];
}
}
}
static Node newNode(int data) {
Node node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return node;
}
static void Main(string[] args) {
Node root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
}
}
JavaScript
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
this.visited = false;
}
}
function postorder(root) {
let n = root;
const parentMap = new Map();
parentMap.set(root, null);
while (n) {
if (n.left && !parentMap.has(n.left)) {
parentMap.set(n.left, n);
n = n.left;
} else if (n.right && !parentMap.has(n.right)) {
parentMap.set(n.right, n);
n = n.right;
} else {
console.log(n.data + " ");
n = parentMap.get(n);
}
}
}
// Test
const root = new Node(8);
root.left = new Node(3);
root.right = new Node(10);
root.left.left = new Node(1);
root.left.right = new Node(6);
root.left.right.left = new Node(4);
root.left.right.right = new Node(7);
root.right.right = new Node(14);
root.right.right.left = new Node(13);
postorder(root);
// This code is contributed by divyansh2212
Output:
1 4 7 6 3 13 14 10 8
Time complexity: O(n) where n is no of nodes in a binary tree
Auxiliary Space: O(n) since using unordered_map
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4