A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://www.geeksforgeeks.org/dsa/postorder-traversal-binary-tree-without-recursion-without-stack/ below:

Postorder traversal of Binary Tree without recursion and without stack

Postorder traversal of Binary Tree without recursion and without stack

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