class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
self.height = 1
class AVLTree:
def __init__(self):
self.root = None
def height(self, node):
if not node:
return 0
return node.height
def balance(self, node):
if not node:
return 0
return self.height(node.left) - self.height(node.right)
def insert(self, root, value):
if not root:
return Node(value)
elif value < root.value:
root.left = self.insert(root.left, value)
else:
root.right = self.insert(root.right, value)
root.height = 1 + max(self.height(root.left), self.height(root.right))
balance = self.balance(root)
# Left rotation
if balance > 1 and value < root.left.value:
return self.right_rotate(root)
# Right rotation
if balance < -1 and value > root.right.value:
return self.left_rotate(root)
# Left-Right rotation
if balance > 1 and value > root.left.value:
root.left = self.left_rotate(root.left)
return self.right_rotate(root)
# Right-Left rotation
if balance < -1 and value < root.right.value:
root.right = self.right_rotate(root.right)
return self.left_rotate(root)
return root
def delete(self, root, value):
if not root:
return root
if value < root.value:
root.left = self.delete(root.left, value)
elif value > root.value:
root.right = self.delete(root.right, value)
else:
if not root.left:
temp = root.right
root = None
return temp
elif not root.right:
temp = root.left
root = None
return temp
temp = self.min_value_node(root.right)
root.value = temp.value
root.right = self.delete(root.right, temp.value)
if not root:
return root
root.height = 1 + max(self.height(root.left), self.height(root.right))
balance = self.balance(root)
# Left rotation
if balance > 1 and self.balance(root.left) >= 0:
return self.right_rotate(root)
# Right rotation
if balance < -1 and self.balance(root.right) <= 0:
return self.left_rotate(root)
# Left-Right rotation
if balance > 1 and self.balance(root.left) < 0:
root.left = self.left_rotate(root.left)
return self.right_rotate(root)
# Right-Left rotation
if balance < -1 and self.balance(root.right) > 0:
root.right = self.right_rotate(root.right)
return self.left_rotate(root)
return root
def left_rotate(self, z):
y = z.right
T2 = y.left
y.left = z
z.right = T2
z.height = 1 + max(self.height(z.left), self.height(z.right))
y.height = 1 + max(self.height(y.left), self.height(y.right))
return y
def right_rotate(self, z):
y = z.left
T3 = y.right
y.right = z
z.left = T3
z.height = 1 + max(self.height(z.left), self.height(z.right))
y.height = 1 + max(self.height(y.left), self.height(y.right))
return y
def min_value_node(self, root):
current = root
while current.left:
current = current.left
return current
def search(self, root, value):
if not root or root.value == value:
return root
if root.value < value:
return self.search(root.right, value)
return self.search(root.left, value)
def insert_value(self, value):
self.root = self.insert(self.root, value)
def delete_value(self, value):
self.root = self.delete(self.root, value)
def search_value(self, value):
return self.search(self.root, value)
# Example usage:
if __name__ == "__main__":
tree = AVLTree()
tree.insert_value(10)
tree.insert_value(20)
tree.insert_value(30)
tree.insert_value(40)
tree.insert_value(50)
print("Tree after insertion:")
# In-order traversal to print the tree
def inorder_traversal(root):
if root:
inorder_traversal(root.left)
print(root.value),
inorder_traversal(root.right)
inorder_traversal(tree.root)
print()
tree.delete_value(20)
print("Tree after deletion of 20:")
inorder_traversal(tree.root)
print()
result = tree.search_value(30)
if result:
print("Node found")
else:
print("Node not found")