class Node:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
self.parent = None
def insert(root, val):
if root is None:
return Node(val)
if val < root.val:
left_child = insert(root.left, val)
root.left = left_child
left_child.parent = root
else:
right_child = insert(root.right, val)
root.right = right_child
right_child.parent = root
return root
def find_node(root, val):
if root is None or root.val == val:
return root
if val < root.val:
return find_node(root.left, val)
else:
return find_node(root.right, val)
def max_node(node):
while node.right:
node = node.right
return node
def inorder_predecessor(node):
# If left subtree exists, predecessor is max in left subtree
if node.left:
return max_node(node.left)
# Otherwise, go up until we find a node that is right child of its parent
curr = node
while curr.parent and curr == curr.parent.left:
curr = curr.parent
return curr.parent
# Build BST
root = None
for v in [5,3,7,2,4,8]:
root = insert(root, v)
# Find node 4
target = find_node(root, 4)
# Find predecessor
pred = inorder_predecessor(target)
if pred:
print(pred.val)
else:
print('No predecessor')Check if node has left subtree to find predecessor there
return max_node(node.left)
Predecessor is max node in left subtree
while curr.parent and curr == curr.parent.left:
Move up until node is right child of its parent
Return parent as predecessor or None if no predecessor