The AVL tree in Python is a self–balancing binary search tree that guarantees the difference of the heights of the left and right subtrees of a node is at most 1. The algorithm is named after its inventors, Georgy Adelson-Velsky, and Evgenii Landis who published their paper in 1962.
The AVL tree keeps its balance through rotations subsequently after adding or removing nodes. This rotation mechanism balances the tree and allocates resources for the best depth search, insertion, and removal procedures.
In Python, AVL trees are implemented usually through classes. The structure respectively contains nodes representing individual elements and methods for insertion, deletion, and rotation to preserve the balance. This data structure shows its usage in the fields where fast search, insertion, and deleting operations are needed to maintain equilibrium and avoid problems.
AVL TreeThe above tree is AVL because the differences between the heights of left and right subtrees for every node are less than or equal to 1.
Operations on AVL Tree in Python
- Insertion: For insertion, we first perform the BST insertion and check the balance factor. If any side of the node gets unbalanced, the BST gets unset and then rotations are done to rebalance the tree.
- Deletion: The process of deletion in an AVL node is based on a standard method utilized for the BST (binary search tree) node deletion. The balancing of each formed node is performed after deletion and required rotations are maintained if any imbalance occurs.
- Searching: Searching in an AVL tree does just the work that a standard BST does as its search method. We evaluate what we are seeking against what the nodes hold and then move left or right accordingly and stop when we find the right value or hit a leaf node.
- Rotating the subtrees in an AVL Tree
- Left Rotation: When a node is inserted into the right subtree of the right subtree, and if the tree gets skewed a balance than we apply a single left rotation.
- Right Rotation: If the node is added to the left subtree of the left subtree, the new AVL tree may not be balanced, so we do a single right rotation.
- Left-Right Rotation: A rotation that begins with a left rotation and then is finished by a right one is referred to as a Left-Right rotation.
- Right-Left Rotation: A rotation that begins with a right rotation and then is finished by a left one is referred to as a right-left rotation.
Step-by-step approach for AVL Tree in Python:
- Node Class: We begin by designing a unique Node class which is used to define individual Nodes of the AVL Tree. The node has a value, its left child, its right child and the height as attribute.
- AVL Tree Class: We are going to construct "AVL Tree" class that will manage the AVL tree implementation. This class will entail methods for the insertions, deletion, searching and balancing.
- Insertion: To add a new node, standard BST tree insertion is done. We make it happen by updating the height of each node from the inserted node to the root. For instance, in case any particular node not in balance, we use rotation to make tree balanced once again.
- Deletion: Deletion of an AVL tree is usually made through the common BST deletion principle. Post deletion we update the height of the each node from the deleted node to the root. We apply a rotation if any node is unbalanced.
- Rotations: We utilize left rotation, right rotation, left & right rotation and right-left rotation techniques to balance AVL tree in a proper manner.
Below is the implementation of the above approach:
Python
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")
OutputTree after insertion:
10 20 30 40 50 ()
Tree after deletion of 20:
10 30 40 50 ()
Node found
Time Complexity :
- Insertion: O(log n) average case, O(n) worst case
- Deletion: O(log n) average case, O(n) worst case
- Search: O(log n) average case, O(n) worst case
Space Complexity: O(n)
Related Articles
Similar Reads
B Tree in Python A B-tree is a self-balancing tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time. B Tree in Python Table of Content Characteristics of B-TreesTraversal of B-Tree in PythonSearch operation in B Tree in PythonInsert opera
14 min read
B+ Tree in Python In computer science, data structures are crucial in efficiently managing and organizing data. Among these, the B+ tree is a powerful and important data structure, widely used in databases and file systems. In this article, we will discuss the concept of B+ trees, exploring their structure, operation
12 min read
Fractal Trees in Python Implementation of Fractal Binary Trees in python. Introduction A fractal tree is known as a tree which can be created by recursively symmetrical branching. The trunk of length 1 splits into two branches of length r, each making an angle q with the direction of the trunk. Both of these branches divid
3 min read
Binary Tree in Python Binary Tree is a non-linear and hierarchical data structure where each node has at most two children referred to as the left child and the right child. The topmost node in a binary tree is called the root, and the bottom-most nodes are called leaves.Introduction to Binary TreeRepresentation of Binar
9 min read
Tree Sort in Python Tree sort is a sorting algorithm that builds a Binary Search Tree (BST) from the elements of the array to be sorted and then performs an in-order traversal of the BST to get the elements in sorted order. In this article, we will learn about the basics of Tree Sort along with its implementation in Py
3 min read
Red Black Tree in Python Red Black Tree is a self-balancing binary search tree where each node has an extra bit representing its color, either red or black. By constraining how nodes are colored during insertions and deletions, red-black trees ensure the tree remains approximately balanced during all operations, allowing fo
11 min read