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
Construct Binary Tree from Inorder and Postorder Traversal in Python
Building a binary tree from its inorder and postorder traversal sequences is a classic tree construction problem. The key insight is that the postorder traversal gives us the root node (last element), while the inorder traversal helps us identify left and right subtrees.
Algorithm Steps
The reconstruction algorithm follows these steps ?
- Take the last element from postorder traversal as the root node
- Find the root's position in inorder traversal to split left and right subtrees
- Recursively build left subtree using elements before root in inorder
- Recursively build right subtree using elements after root in inorder
Implementation
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def print_tree(root):
# Print using inorder traversal
if root is not None:
print_tree(root.left)
print(root.data, end=', ')
print_tree(root.right)
class Solution:
def buildTree(self, inorder, postorder):
if not inorder or not postorder:
return None
# Last element in postorder is the root
root = TreeNode(postorder.pop())
root_index = inorder.index(root.data)
# Build right subtree first (postorder: left, right, root)
root.right = self.buildTree(inorder[root_index + 1:], postorder)
root.left = self.buildTree(inorder[:root_index], postorder)
return root
# Example usage
solution = Solution()
inorder = [9, 3, 15, 20, 7]
postorder = [9, 15, 7, 20, 3]
tree = solution.buildTree(inorder, postorder)
print("Inorder traversal of constructed tree:")
print_tree(tree)
Inorder traversal of constructed tree: 9, 3, 15, 20, 7,
How It Works
The algorithm leverages the properties of postorder traversal (left − right − root). Since we process the postorder list from right to left, we build the right subtree before the left subtree. This ensures correct tree construction.
Step−by−Step Example
# Initial arrays
inorder = [9, 3, 15, 20, 7]
postorder = [9, 15, 7, 20, 3]
# Step 1: Root = 3 (last in postorder)
# Split inorder: left=[9], right=[15, 20, 7]
# Step 2: Build right subtree with [15, 20, 7] and remaining postorder
# Root = 20, Split: left=[15], right=[7]
# Step 3: Continue recursively until all nodes are processed
def buildTree_with_debug(inorder, postorder, depth=0):
indent = " " * depth
print(f"{indent}Building tree with inorder={inorder}, postorder={postorder}")
if not inorder or not postorder:
return None
root_val = postorder.pop()
root = TreeNode(root_val)
root_index = inorder.index(root_val)
print(f"{indent}Root: {root_val}, Index: {root_index}")
# Build right first, then left
root.right = buildTree_with_debug(inorder[root_index + 1:], postorder, depth + 1)
root.left = buildTree_with_debug(inorder[:root_index], postorder, depth + 1)
return root
# Debug example
solution_debug = Solution()
inorder_debug = [9, 3, 15, 20, 7]
postorder_debug = [9, 15, 7, 20, 3]
print("Debug trace:")
tree_debug = buildTree_with_debug(inorder_debug.copy(), postorder_debug.copy())
Debug trace:
Building tree with inorder=[9, 3, 15, 20, 7], postorder=[9, 15, 7, 20, 3]
Root: 3, Index: 1
Building tree with inorder=[15, 20, 7], postorder=[9, 15, 7, 20]
Root: 20, Index: 1
Building tree with inorder=[7], postorder=[9, 15, 7]
Root: 7, Index: 0
Building tree with inorder=[15], postorder=[9, 15]
Root: 15, Index: 0
Building tree with inorder=[9], postorder=[9]
Root: 9, Index: 0
Time and Space Complexity
| Complexity | Value | Explanation |
|---|---|---|
| Time | O(n²) | Finding index in inorder for each node |
| Space | O(n) | Recursion depth and tree storage |
Conclusion
Building a binary tree from inorder and postorder traversals requires understanding that postorder's last element is always the root. Use inorder traversal to split left and right subtrees, and build right subtree before left due to postorder's nature.
