Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 215ba70

Browse files
AVL-tree in Python
1 parent 4a89dda commit 215ba70

File tree

1 file changed

+303
-0
lines changed

1 file changed

+303
-0
lines changed

‎Trees/avl-tree.py

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
# Copyright (C) Deepali Srivastava - All Rights Reserved
2+
# This code is part of DSA course available on CourseGalaxy.com
3+
4+
class Node:
5+
def __init__(self,value):
6+
self.info = value
7+
self.lchild = None
8+
self.rchild = None
9+
self.balance = 0
10+
11+
class AVLTree:
12+
13+
taller = False
14+
shorter = False
15+
16+
def __init__(self):
17+
self.root = None
18+
19+
20+
def isEmpty(self,x):
21+
return self.root == None
22+
23+
24+
def display(self):
25+
self._display(self.root,0)
26+
print()
27+
28+
29+
def _display(self,p,level):
30+
if p is None:
31+
return
32+
self._display(p.rchild, level+1)
33+
print()
34+
35+
for i in range(level):
36+
print(" ", end='')
37+
print(p.info)
38+
self._display(p.lchild, level+1)
39+
40+
41+
def inorder(self):
42+
self._inorder(self.root)
43+
print()
44+
45+
46+
def _inorder(self, p):
47+
if p is None :
48+
return
49+
self._inorder(p.lchild)
50+
print(p.info, end = " ")
51+
self._inorder(p.rchild)
52+
53+
54+
def insert(self,x):
55+
self.root = self._insert(self.root, x)
56+
57+
58+
def _insert(self,p,x):
59+
if p is None:
60+
p = Node(x)
61+
AVLTree.taller = True
62+
elif x < p.info:
63+
p.lchild = self._insert(p.lchild, x)
64+
if AVLTree.taller == True:
65+
p = self._insertionLeftSubtreeCheck(p)
66+
elif x > p.info :
67+
p.rchild = self._insert(p.rchild, x)
68+
if AVLTree.taller == True:
69+
p = self._insertionRightSubtreeCheck(p)
70+
else:
71+
print(x," already present in the tree")
72+
AVLTree.taller = False
73+
return p
74+
75+
def _insertionLeftSubtreeCheck(self, p):
76+
if p.balance == 0: # Case L_1 : was balanced
77+
p.balance = 1 # now left heavy
78+
elif p.balance == -1: # Case L_2 : was right heavy
79+
p.balance = 0 # now balanced
80+
AVLTree.taller = False
81+
else: # p.balance = 0 Case L_3 : was left heavy
82+
p = self._insertionLeftBalance(p) # Left Balancing
83+
AVLTree.taller = False
84+
return p
85+
86+
87+
def _insertionRightSubtreeCheck(self, p):
88+
if p.balance == 0: # Case R_1 : was balanced
89+
p.balance = -1 # now right heavy
90+
elif p.balance == 1: # Case R_2 : was left heavy
91+
p.balance = 0 # now balanced
92+
AVLTree.taller = False
93+
else: # p.balance == 1 Case R_3: Right heavy
94+
p = self._insertionRightBalance(p) # Right Balancing
95+
AVLTree.taller = False
96+
return p
97+
98+
def _insertionLeftBalance(self, p):
99+
a = p.lchild
100+
if a.balance == 1: # Case L_3A : Insertion in AL
101+
p.balance = 0
102+
a.balance = 0
103+
p = self._rotateRight(p)
104+
else: # Case L_3B : Insertion in AR
105+
b = a.rchild
106+
if b.balance == 1: # Case L_3B2 : Insertion in BL
107+
p.balance = -1
108+
a.balance = 0
109+
elif b.balance == -1: # Case L_3B2 : Insertion in BR
110+
p.balance = 0
111+
a.balance = 1
112+
else: # b.balance == 0 Case L_3B2 : B is the newly inserted node
113+
p.balance = 0
114+
a.balance = 0
115+
b.balance = 0
116+
p.lchild = self._rotateLeft(a)
117+
p = self._rotateRight(p)
118+
return p
119+
120+
121+
def _insertionRightBalance(self,p):
122+
a = p.rchild
123+
if a.balance == -1: # Case R_3A : Insertion in AR
124+
p.balance = 0
125+
a.balance = 0
126+
p = self._rotateLeft(p)
127+
else: # Case R_3B : Insertion in AL
128+
b = a.lchild
129+
if b.balance == -1: # Insertion in BR
130+
p.balance = 1
131+
a.balance = 0
132+
elif b.balance == 1: # Insertion in BL
133+
p.balance = 0
134+
a.balance = -1
135+
else: # B is the newly inserted node
136+
p.balance = 0
137+
a.balance = 0
138+
139+
b.balance = 0
140+
p.rchild = self._rotateRight(a)
141+
p = self._rotateLeft(p)
142+
return p
143+
144+
145+
def _rotateLeft(self, p):
146+
a = p.rchild
147+
p.rchild = a.lchild
148+
a.lchild = p
149+
return a
150+
151+
def _rotateRight(self, p):
152+
a = p.lchild
153+
p.lchild = a.rchild
154+
a.rchild = p
155+
return a
156+
157+
158+
def delete(self,x):
159+
self.root = self._delete(self.root, x)
160+
161+
162+
def _delete(self, p, x):
163+
if p is None:
164+
print(x , " not found")
165+
AVLTree.shorter = False
166+
return p
167+
168+
if x < p.info: # delete from left subtree
169+
p.lchild = self._delete(p.lchild, x)
170+
if AVLTree.shorter == True :
171+
p = self._deletionLeftSubtreeCheck(p)
172+
elif x > p.info: # delete from right subtree
173+
p.rchild = self._delete(p.rchild, x)
174+
if AVLTree.shorter == True :
175+
p = self._deletionRightSubtreeCheck(p)
176+
else:
177+
# key to be deleted is found
178+
if p.lchild is not None and p.rchild is not None: # 2 children
179+
s = p.rchild
180+
while s.lchild is not None:
181+
s = s.lchild
182+
p.info = s.info
183+
p.rchild = self._delete(p.rchild,s.info)
184+
if AVLTree.shorter == True :
185+
p = self._deletionRightSubtreeCheck(p)
186+
else: # 1 child or no child
187+
if p.lchild is not None: # only left child
188+
ch = p.lchild
189+
else: # only right child or no child
190+
ch = p.rchild
191+
p = ch
192+
AVLTree.shorter = True
193+
return p
194+
195+
196+
def _deletionLeftSubtreeCheck(self, p):
197+
if p.balance == 0: # Case L_1 : was balanced
198+
p.balance = -1 # now right heavy
199+
AVLTree.shorter = False
200+
elif p.balance == 1: # Case L_2 : was left heavy
201+
p.balance = 0 # now balanced
202+
else: # p.balance == -1 Case L_3 : was right heavy
203+
p = self._deletionRightBalance(p) #Right Balancing
204+
return p
205+
206+
207+
def _deletionRightSubtreeCheck(self, p):
208+
if p.balance == 0: # Case R_1 : was balanced
209+
p.balance = 1 # now left heavy
210+
AVLTree.shorter = False
211+
elif p.balance == -1: # Case R_2 : was right heavy
212+
p.balance = 0 # now balanced
213+
else: #p.balance == 1 Case R_3 : was left heavy
214+
p = self._deletionLeftBalance(p) #Left Balancing
215+
return p
216+
217+
def _deletionLeftBalance(self, p):
218+
a = p.lchild
219+
if a.balance == 0: # Case R_3A
220+
a.balance = -1
221+
AVLTree.shorter = False
222+
p = self._rotateRight(p)
223+
elif a.balance == 1: # Case R_3B
224+
p.balance = 0
225+
a.balance = 0
226+
p = self._rotateRight(p)
227+
else : # Case R_3C
228+
b = a.rchild
229+
if b.balance == 0: # Case R_3C1
230+
p.balance = 0
231+
a.balance = 0
232+
elif b.balance == -1: # Case R_3C2
233+
p.balance = 0
234+
a.balance = 1
235+
else: # Case R_3C3
236+
p.balance = -1
237+
a.balance = 0
238+
b.balance = 0
239+
p.lchild = self._rotateLeft(a)
240+
p = self._rotateRight(p)
241+
return p
242+
243+
def _deletionRightBalance(self, p):
244+
a = p.rchild
245+
if a.balance == 0 : # Case L_3A
246+
a.balance = 1
247+
AVLTree.shorter = False
248+
p = self._rotateLeft(p)
249+
elif a.balance == -1 : # Case L_3B
250+
p.balance = 0
251+
a.balance = 0
252+
p = self._rotateLeft(p)
253+
else: # Case L_3C
254+
b = a.lchild
255+
if b.balance == 0: # Case L_3C1
256+
p.balance = 0
257+
a.balance = 0
258+
elif b.balance == 1: # Case L_3C2
259+
p.balance = 0
260+
a.balance = -1
261+
else: # b.balance = -1: # Case L_3C3
262+
p.balance = 1
263+
a.balance = 0
264+
b.balance = 0
265+
p.rchild = self._rotateRight(a)
266+
p = self._rotateLeft(p)
267+
return p
268+
269+
270+
271+
272+
273+
##############################################################################################
274+
275+
if __name__ == '__main__':
276+
277+
tree = AVLTree()
278+
279+
while True:
280+
print("1.Display Tree")
281+
print("2.Insert a new node")
282+
print("3.Delete a node")
283+
print("4.Inorder Traversal")
284+
print("5.Quit")
285+
choice = int(input("Enter your choice : "))
286+
287+
if choice == 1:
288+
tree.display()
289+
elif choice == 2:
290+
x = int(input("Enter the key to be inserted : "))
291+
tree.insert(x)
292+
elif choice == 3:
293+
x = int(input("Enter the key to be deleted : "))
294+
tree.delete(x)
295+
elif choice == 4:
296+
tree.inorder()
297+
elif choice == 5:
298+
break
299+
else:
300+
print("Wrong choice")
301+
print()
302+
303+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /