Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Binary Tree Postorder Traversal in Python
Binary tree postorder traversal visits nodes in the order: left subtree, right subtree, then root. This article demonstrates an iterative approach using a stack with node-state pairs to achieve postorder traversal without recursion.
Algorithm Steps
The iterative postorder traversal uses a stack to simulate the recursive calls ?
If root is null, return empty array
Create a stack with pairs [node, visited_flag]
-
While stack is not empty:
Pop node from stack
-
If visited_flag is 0 (first visit):
Push [current, 1] back to stack
Push right child if exists
Push left child if exists
If visited_flag is 1 (second visit), add node data to result
Implementation
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
class Solution:
def postorderTraversal(self, root):
if not root:
return []
result = []
stack = [[root, 0]] # [node, visited_flag]
while stack:
node = stack.pop()
if node[1] == 0: # First visit
current = node[0]
stack.append([current, 1]) # Mark as visited
# Push right first, then left (stack is LIFO)
if current.right:
stack.append([current.right, 0])
if current.left:
stack.append([current.left, 0])
else: # Second visit - process node
result.append(node[0].data)
return result
# Create the binary tree
root = TreeNode(-10)
root.left = TreeNode(9)
root.right = TreeNode(10)
root.right.left = TreeNode(15)
root.right.right = TreeNode(7)
# Perform postorder traversal
solution = Solution()
result = solution.postorderTraversal(root)
print("Postorder traversal:", result)
Postorder traversal: [9, 15, 7, 10, -10]
How It Works
The algorithm uses a two-phase approach for each node ?
# Trace through the algorithm step by step
def postorder_with_trace(root):
if not root:
return []
result = []
stack = [[root, 0]]
step = 1
while stack:
node = stack.pop()
print(f"Step {step}: Processing {node[0].data}, visited={node[1]}")
if node[1] == 0: # First visit
current = node[0]
stack.append([current, 1])
print(f" Marking {current.data} for later processing")
if current.right:
stack.append([current.right, 0])
print(f" Added right child: {current.right.data}")
if current.left:
stack.append([current.left, 0])
print(f" Added left child: {current.left.data}")
else: # Second visit
result.append(node[0].data)
print(f" Added {node[0].data} to result")
step += 1
print(f" Current result: {result}")
print()
return result
# Example with trace
root = TreeNode(-10)
root.left = TreeNode(9)
root.right = TreeNode(10)
root.right.left = TreeNode(15)
root.right.right = TreeNode(7)
print("Tracing postorder traversal:")
final_result = postorder_with_trace(root)
print(f"Final result: {final_result}")
Tracing postorder traversal: Step 1: Processing -10, visited=0 Marking -10 for later processing Added right child: 10 Added left child: 9 Current result: [] Step 2: Processing 9, visited=0 Marking 9 for later processing Current result: [] Step 3: Processing 9, visited=1 Added 9 to result Current result: [9] Step 4: Processing 10, visited=0 Marking 10 for later processing Added right child: 7 Added left child: 15 Current result: [9] Step 5: Processing 15, visited=0 Marking 15 for later processing Current result: [9] Step 6: Processing 15, visited=1 Added 15 to result Current result: [9, 15] Step 7: Processing 7, visited=0 Marking 7 for later processing Current result: [9, 15] Step 8: Processing 7, visited=1 Added 7 to result Current result: [9, 15, 7] Step 9: Processing 10, visited=1 Added 10 to result Current result: [9, 15, 7, 10] Step 10: Processing -10, visited=1 Added -10 to result Current result: [9, 15, 7, 10, -10] Final result: [9, 15, 7, 10, -10]
Key Points
Two-phase processing: Each node is visited twice - first to explore children, second to process
Stack order: Right child pushed before left child due to LIFO nature
Time complexity: O(n) where n is the number of nodes
Space complexity: O(h) where h is the height of the tree
Conclusion
Iterative postorder traversal uses a stack with node-state pairs to achieve left-right-root ordering. The two-phase approach ensures children are processed before their parent, maintaining postorder sequence without recursion.
