Skip to content

Commit 65e2aa4

Browse files
committed
Added AVL Trees in DSA section
1 parent d2d6db0 commit 65e2aa4

File tree

2 files changed

+187
-1
lines changed

2 files changed

+187
-1
lines changed

contrib/ds-algorithms/avl-trees.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# AVL Tree
2+
3+
In Data Structures and Algorithms, an **AVL Tree** is a self-balancing binary search tree (BST) where the difference between heights of left and right subtrees cannot be more than one for all nodes. It ensures that the tree remains balanced, providing efficient search, insertion, and deletion operations.
4+
5+
## Points to be Remembered
6+
7+
- **Balance Factor**: The difference in heights between the left and right subtrees of a node. It should be -1, 0, or +1 for all nodes in an AVL tree.
8+
- **Rotations**: Tree rotations (left, right, left-right, right-left) are used to maintain the balance factor within the allowed range.
9+
10+
## Real Life Examples of AVL Trees
11+
12+
- **Databases**: AVL trees can be used to maintain large indexes for database tables, ensuring quick data retrieval.
13+
- **File Systems**: Some file systems use AVL trees to keep track of free and used memory blocks.
14+
15+
## Applications of AVL Trees
16+
17+
AVL trees are used in various applications in Computer Science:
18+
19+
- **Database Indexing**
20+
- **Memory Allocation**
21+
- **Network Routing Algorithms**
22+
23+
Understanding these applications is essential for Software Development.
24+
25+
## Operations in AVL Tree
26+
27+
Key operations include:
28+
29+
- **INSERT**: Insert a new element into the AVL tree.
30+
- **SEARCH**: Find the position of an element in the AVL tree.
31+
- **DELETE**: Remove an element from the AVL tree.
32+
33+
## Implementing AVL Tree in Python
34+
35+
```python
36+
class AVLTreeNode:
37+
def __init__(self, key):
38+
self.key = key
39+
self.left = None
40+
self.right = None
41+
self.height = 1
42+
43+
class AVLTree:
44+
def insert(self, root, key):
45+
if not root:
46+
return AVLTreeNode(key)
47+
48+
if key < root.key:
49+
root.left = self.insert(root.left, key)
50+
else:
51+
root.right = self.insert(root.right, key)
52+
53+
root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right))
54+
balance = self.getBalance(root)
55+
56+
if balance > 1 and key < root.left.key:
57+
return self.rotateRight(root)
58+
if balance < -1 and key > root.right.key:
59+
return self.rotateLeft(root)
60+
if balance > 1 and key > root.left.key:
61+
root.left = self.rotateLeft(root.left)
62+
return self.rotateRight(root)
63+
if balance < -1 and key < root.right.key:
64+
root.right = self.rotateRight(root.right)
65+
return self.rotateLeft(root)
66+
67+
return root
68+
69+
def search(self, root, key):
70+
if not root or root.key == key:
71+
return root
72+
73+
if key < root.key:
74+
return self.search(root.left, key)
75+
76+
return self.search(root.right, key)
77+
78+
def delete(self, root, key):
79+
if not root:
80+
return root
81+
82+
if key < root.key:
83+
root.left = self.delete(root.left, key)
84+
elif key > root.key:
85+
root.right = self.delete(root.right, key)
86+
else:
87+
if root.left is None:
88+
temp = root.right
89+
root = None
90+
return temp
91+
elif root.right is None:
92+
temp = root.left
93+
root = None
94+
return temp
95+
96+
temp = self.getMinValueNode(root.right)
97+
root.key = temp.key
98+
root.right = self.delete(root.right, temp.key)
99+
100+
if root is None:
101+
return root
102+
103+
root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right))
104+
balance = self.getBalance(root)
105+
106+
if balance > 1 and self.getBalance(root.left) >= 0:
107+
return self.rotateRight(root)
108+
if balance < -1 and self.getBalance(root.right) <= 0:
109+
return self.rotateLeft(root)
110+
if balance > 1 and self.getBalance(root.left) < 0:
111+
root.left = self.rotateLeft(root.left)
112+
return self.rotateRight(root)
113+
if balance < -1 and self.getBalance(root.right) > 0:
114+
root.right = self.rotateRight(root.right)
115+
return self.rotateLeft(root)
116+
117+
return root
118+
119+
def rotateLeft(self, z):
120+
y = z.right
121+
T2 = y.left
122+
y.left = z
123+
z.right = T2
124+
z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right))
125+
y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right))
126+
return y
127+
128+
def rotateRight(self, z):
129+
y = z.left
130+
T3 = y.right
131+
y.right = z
132+
z.left = T3
133+
z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right))
134+
y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right))
135+
return y
136+
137+
def getHeight(self, root):
138+
if not root:
139+
return 0
140+
return root.height
141+
142+
def getBalance(self, root):
143+
if not root:
144+
return 0
145+
return self.getHeight(root.left) - self.getHeight(root.right)
146+
147+
def getMinValueNode(self, root):
148+
if root is None or root.left is None:
149+
return root
150+
return self.getMinValueNode(root.left)
151+
152+
def preOrder(self, root):
153+
if not root:
154+
return
155+
print(root.key, end=' ')
156+
self.preOrder(root.left)
157+
self.preOrder(root.right)
158+
159+
#Example usage
160+
avl_tree = AVLTree()
161+
root = None
162+
163+
root = avl_tree.insert(root, 10)
164+
root = avl_tree.insert(root, 20)
165+
root = avl_tree.insert(root, 30)
166+
root = avl_tree.insert(root, 40)
167+
root = avl_tree.insert(root, 50)
168+
root = avl_tree.insert(root, 25)
169+
170+
print("Preorder traversal of the AVL tree is:")
171+
avl_tree.preOrder(root)
172+
```
173+
174+
## Output
175+
176+
```markdown
177+
Preorder traversal of the AVL tree is:
178+
30 20 10 25 40 50
179+
```
180+
181+
## Complexity Analysis
182+
183+
- **Insertion**: O(logn). Inserting a node involves traversing the height of the tree, which is logarithmic due to the balancing property.
184+
- **Search**: O(logn). Searching for a node involves traversing the height of the tree.
185+
- **Deletion**: O(log⁡n). Deleting a node involves traversing and potentially rebalancing the tree, maintaining the logarithmic height.

contrib/ds-algorithms/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515
- [Trie](trie.md)
1616
- [Two Pointer Technique](two-pointer-technique.md)
1717
- [Hashing through Linear Probing](hashing-linear-probing.md)
18-
- [Hashing through Chaining](hashing-chaining.md)
18+
- [Hashing through Chaining](hashing-chaining.md)
19+
- [AVL Trees](avl-trees.md)

0 commit comments

Comments
 (0)