Welcome to our comprehensive guide on AVL Deletion! In this lesson, we'll dive deep into understanding AVL trees, their importance, and the process of deleting a node from an AVL tree.
AVL trees are self-balancing binary search trees, named after their inventors Adelson-Velsky and Landis. They maintain a balance by adjusting the height of the tree during insertions and deletions. This balance ensures that the height of the left and right subtrees of every node differs by at most one.
AVL trees are useful in scenarios where the order of insertion and deletion of elements is important, and the tree needs to be kept balanced. They provide faster search, insert, and delete operations compared to ordinary binary search trees.
The AVL deletion process involves the following steps:
Locate the Node to be Deleted
Case 1: Deleting a Leaf Node
def delete_leaf_node(root, key):
if root is None:
return root
if root.key > key:
root.left = delete_leaf_node(root.left, key)
elif root.key < key:
root.right = delete_leaf_node(root.right, key)
else:
if root.left is None:
return root.right
elif root.right is None:
return root.left
# ... (Handle cases where the node has children)Case 2: Deleting an Internal Node with One Child
def delete_node_with_one_child(root, key):
if root is None:
return root
if root.key > key:
root.left = delete_node_with_one_child(root.left, key)
elif root.key < key:
root.right = delete_node_with_one_child(root.right, key)
else:
if root.left is None:
return root.right
elif root.right is None:
return root.left
# ... (Handle cases where the node has children)Case 3: Deleting an Internal Node with Two Children
def find_successor(node):
if node.right is not None:
return find_min(node.right)
parent, current = node.parent, node
while current is not node.left:
parent = current
current = current.parent
parent.left = current.right
if current.right is not None:
current.right.parent = parent
return node
def delete_node_with_two_children(root, key):
if root is None:
return root
if root.key > key:
root.left = delete_node_with_two_children(root.left, key)
elif root.key < key:
root.right = delete_node_with_two_children(root.right, key)
else:
if root.left is None:
return root.right
elif root.right is None:
return root.left
# ... (Handle cases where the node has children)
def rebalance_tree(node):
if node.balance_factor > 1 and node.right.balance_factor >= 0:
node.balance_factor -= 1
node.right.balance_factor += 1
node = rotate_right(node)
if node.balance_factor > 1 and node.right.balance_factor < 0:
node.balance_factor -= 1
node.right = rotate_left(node.right)
node = rotate_right(node)
if node.balance_factor < -1 and node.left.balance_factor <= 0:
node.balance_factor += 1
node.left.balance_factor -= 1
node = rotate_left(node)
if node.balance_factor < -1 and node.left.balance_factor > 0:
node.balance_factor += 1
node.left = rotate_right(node.left)
node = rotate_left(node)What is the main purpose of AVL trees?
That's it for our AVL Deletion guide! Now you have a good understanding of AVL trees and the process of deleting nodes from them. Happy coding! š”šÆš