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 a Binary Search Tree from given postorder in Python
A Binary Search Tree (BST) can be constructed from its postorder traversal sequence. Since a BST's inorder traversal is always sorted, we can derive the inorder sequence and use both traversals to rebuild the tree.
Algorithm Steps
The key insight is that for a BST, the inorder traversal is simply the sorted version of the postorder sequence.
Create inorder sequence by sorting the postorder elements
Use recursive approach with inorder and postorder arrays
Last element in postorder is always the root
Split inorder array at root position to get left and right subtrees
Build right subtree first (important for postorder)
Implementation
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def print_tree_inorder(root):
"""Print tree in inorder traversal"""
if root is not None:
print_tree_inorder(root.left)
print(root.data, end=', ')
print_tree_inorder(root.right)
class Solution:
def buildTree(self, inorder, postorder):
"""Build BST from inorder and postorder traversals"""
if inorder:
# Last element in postorder is the root
root = TreeNode(postorder.pop())
# Find root position in inorder
ind = inorder.index(root.data)
# Build right subtree first (postorder property)
root.right = self.buildTree(inorder[ind+1:], postorder)
# Build left subtree
root.left = self.buildTree(inorder[:ind], postorder)
return root
# Example usage
solution = Solution()
postorder = [9, 15, 7, 20, 3]
inorder = sorted(postorder) # For BST: [3, 7, 9, 15, 20]
print("Postorder:", postorder)
print("Inorder (sorted):", inorder)
# Build the tree
root = solution.buildTree(inorder, postorder)
print("Tree inorder traversal: ", end="")
print_tree_inorder(root)
Postorder: [9, 15, 7, 20, 3] Inorder (sorted): [3, 7, 9, 15, 20] Tree inorder traversal: 3, 9, 15, 7, 20,
How It Works
The algorithm leverages the property that in postorder traversal, the root is always the last element. For each recursive call:
Root identification: Pop the last element from postorder
Subtree division: Find root index in inorder to split left/right subtrees
Right-first recursion: Build right subtree before left (postorder property)
Alternative Implementation
Here's a more direct approach that constructs the BST using only the postorder sequence ?
class TreeNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
class BSTConstructor:
def __init__(self):
self.index = 0
def construct_from_postorder(self, postorder):
"""Construct BST directly from postorder"""
self.index = len(postorder) - 1
return self._build(postorder, float('-inf'), float('inf'))
def _build(self, postorder, min_val, max_val):
if self.index < 0:
return None
val = postorder[self.index]
# Check if current value fits in the BST range
if val < min_val or val > max_val:
return None
self.index -= 1
root = TreeNode(val)
# Build right subtree first (postorder: left, right, root)
root.right = self._build(postorder, val, max_val)
root.left = self._build(postorder, min_val, val)
return root
# Example
constructor = BSTConstructor()
postorder = [9, 15, 7, 20, 3]
root = constructor.construct_from_postorder(postorder)
print("BST constructed from postorder:", postorder)
print("Inorder verification: ", end="")
print_tree_inorder(root)
BST constructed from postorder: [9, 15, 7, 20, 3] Inorder verification: 3, 9, 15, 7, 20,
Conclusion
Constructing a BST from postorder traversal can be done using the sorted inorder approach or directly with range constraints. The key is understanding that postorder processes root nodes last, requiring right-subtree-first recursion.
