Trim a BST
Initialize root and parameters
The initial BST is constructed with root value 3, and the range [1,3] is set. No pruning has started yet.
root = TreeNode(3)
root.left = TreeNode(0)
root.right = TreeNode(4)
low, high = 1, 3Move root down because root.val (3) is within [1,3]
Check if root.val is outside the range. Since 3 is within [1,3], root remains at node 3.
while root and (root.val < low or root.val > high):
if root.val < low:
root = root.right
elif root.val > high:
root = root.leftStart trimming left subtree from root (node 3)
Set current pointer 'cur' to root to begin trimming the left subtree.
cur = rootCheck left child of node 3 (node 0) for pruning
Node 3's left child is node 0, which has value less than low (1). We will prune node 0 by moving left pointer to node 0's right child (node 2).
while cur.left and cur.left.val < low:
cur.left = cur.left.rightMove cur pointer down to left child (node 2) to continue left subtree trimming
After pruning node 0, move cur to its left child node 2 to check if further pruning is needed.
cur = cur.leftCheck left child of node 2 (node 1) for pruning
Node 2's left child is node 1, which is within the range [1,3], so no pruning is needed here.
while cur.left and cur.left.val < low:
cur.left = cur.left.rightMove cur pointer down to left child (node 1) to continue left subtree trimming
Move cur to node 1 to check if it has left children needing pruning.
cur = cur.leftLeft subtree trimming complete, start trimming right subtree from root (node 3)
Set cur pointer back to root to begin trimming the right subtree.
cur = rootCheck right child of node 3 (node 2) for pruning
Node 3's right child is node 2, which has value greater than high (3). We prune node 2 by moving right pointer to node 2's left child (node 4).
while cur.right and cur.right.val > high:
cur.right = cur.right.leftMove cur pointer down to right child (node 4) to continue right subtree trimming
Move cur to its right child node 4 to check if further pruning is needed.
cur = cur.rightReturn the trimmed root
The root node 3 now points to a left subtree rooted at node 2 (which has left child 1) and no right subtree. This is the trimmed BST.
return rootclass TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def trimBST(root, low, high):
# STEP 2: Move root to valid range
while root and (root.val < low or root.val > high):
if root.val < low:
root = root.right # STEP 2: root moves right
elif root.val > high:
root = root.left # STEP 2: root moves left
if not root:
return None
# STEP 3: Trim left subtree
cur = root # STEP 3
while cur:
while cur.left and cur.left.val < low:
cur.left = cur.left.right # STEP 4: prune left child
cur = cur.left # STEP 5: move cur down left
# STEP 8: Trim right subtree
cur = root # STEP 8
while cur:
while cur.right and cur.right.val > high:
cur.right = cur.right.left # STEP 9: prune right child
cur = cur.right # STEP 10: move cur down right
return root # STEP 11
if __name__ == '__main__':
root = TreeNode(3)
root.left = TreeNode(0)
root.right = TreeNode(4)
root.left.right = TreeNode(2)
root.left.right.left = TreeNode(1)
low, high = 1, 3
trimmed = trimBST(root, low, high)
def print_inorder(node):
if not node:
return
print_inorder(node.left)
print(node.val, end=' ')
print_inorder(node.right)
print_inorder(trimmed)Key Takeaways
This step ensures the trimmed tree's root is always valid, which is not obvious from code alone.
Seeing pointer updates visually clarifies how pruning avoids recursion and preserves BST structure.
The symmetry of left and right pruning is easier to grasp when watching each pointer move.
