Open In App

Postorder traversal of Binary Tree without recursion and without stack

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:

• Initialize a pointer temp to the root node of the binary tree.
• Initialize an empty unordered set visited to keep track of visited nodes.
• While temp is not null and temp is not already visited (i.e., temp is not in visited set):
a. If temp has a left child and the left child is not already visited, set temp to the left child.
b. Else if temp has a right child and the right child is not already visited, set temp to the right child.
c. Else, print the data of the current node temp, add temp to visited set, and set temp to the root node.
• Return from the function.

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 ``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 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 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 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``      ``{``        ``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

 ``

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 ``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

 ``

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 ``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 parentMap;``    ``parentMap.insert(pair(root, nullptr));` `    ``while` `(n) {``        ``if` `(n->left && parentMap.find(n->left) == parentMap.end()) {``            ``parentMap.insert(pair(n->left, n));``            ``n = n->left;``        ``}``        ``else` `if` `(n->right && parentMap.find(n->right) == parentMap.end()) {``            ``parentMap.insert(pair(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 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 parentMap = ``new` `Dictionary();` `  ``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