Welcome back to CodeYourCraft! Today, we're diving into an interesting problem known as Recover BST (Binary Search Tree) - a scenario where two nodes in a Binary Search Tree have been swapped, and we need to find and restore the original order. Let's get started! šÆ
A Binary Search Tree (BST) is a data structure where each node has at most two children (left and right). It follows the property that for every node, the left subtree's values are less than the node's value, and the right subtree's values are greater than the node's value. This property helps us perform efficient search, insert, and delete operations. š
Imagine a BST with the following structure:
10
/ \
8 12
/ \
4 11
Now, suppose two nodes are swapped: 8 and 11. The tree now looks like this:
10
/ \
11 12
/ \
4 11
Here, the BST property is violated because 11 appears in both the left and right subtrees of 10. Our goal is to find and restore the original order.
There are two common methods to solve this problem: Morris Traversal and Inorder Recursive Traversal with two stack data structures. We'll explore both methods in detail.
Morris Traversal is an in-place, iterative algorithm for traversing a BST. It's particularly useful in this problem because it allows us to detect swapped nodes.
curr) is null, we've reached the end of the traversal.curr is null, we visit the left child (prev).left) is not null, make prev the right child of left and set left as the current node. Skip this step if left is already being processed.prev.prev, check if prev's inorder successor (the smallest node in the right subtree) exists. If it doesn't, prev is a swapped node.prev has a right child, set curr to the right child and go back to step 2.prev doesn't have a right child, set prev's right child to the current node (if not null) and set curr to the left child of the current node. Go back to step 2.class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def findSwapped(root):
prev = None
curr = root
while curr:
if not curr.left:
curr = curr.right
continue
prev = curr.left
curr = curr.left
while curr and curr != prev:
curr = curr.right
if not curr:
print(f"Swapped nodes: {prev.key}, {curr.key}")
prev.right = curr.left
curr.left = prev
curr = prev.right
else:
curr = curr.left
root = Node(10)
root.left = Node(8)
root.right = Node(12)
root.left.right = Node(4)
root.right.right = Node(11)
findSwapped(root)This method involves using two stacks (inorderStack and recStack) and inorder traversal of the BST. The basic idea is to maintain the original order of the nodes while swapping nodes.
inorder(root, inorderStack).curr) onto recStack when visiting the left subtree.curr has been visited before, swap the top nodes from inorderStack and recStack.curr) from inorderStack.curr) from inorderStack and push it onto recStack.inorderStack and recStack.def inorder(node, inorderStack):
if node:
inorder(node.left, inorderStack)
inorderStack.append(node)
visit(node)
inorder(node.right, inorderStack)
def visit(node):
recStack.append(node)
if node.key == prev.key:
print(f"Swapped nodes: {prev.key}, {node.key}")
prev.key, node.key = node.key, prev.key
root = Node(10)
root.left = Node(8)
root.right = Node(12)
root.left.right = Node(4)
root.right.right = Node(11)
inorderStack = []
recStack = []
prev = None
inorder(root, inorderStack)What property does a Binary Search Tree (BST) follow?
Today, we learned about the Recover BST problem and explored two methods to solve it: Morris Traversal and Inorder Recursive Traversal with two stack data structures. By understanding these techniques, you've taken a step closer to mastering BSTs and data structures in general. Keep practicing, and happy coding! š”