-
Notifications
You must be signed in to change notification settings - Fork 368
/
Copy pathAVLTree.py
168 lines (129 loc) · 4.44 KB
/
AVLTree.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# tree node
class Node(object):
def __init__(self, ele):
self.data = ele
self.left = None
self.right = None
self.height = 1
class AvlTree(object):
# insert method
def insertNode(self, node, ele):
if not node:
return Node(ele)
elif ele < node.val:
node.left = self.insertNode(node.left, ele)
else:
node.right = self.insertNode(node.right, ele)
# height updation
node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right))
balance = self.getBalance(node)
# ll rotation
if balance > 1 and ele < node.left.val:
return self.rightRotate(node)
# rr rotation
if balance < -1 and ele > node.right.val:
return self.leftRotate(node)
# lr rotation
if balance > 1 and ele > node.left.val:
node.left = self.leftRotate(node.left)
return self.rightRotate(node)
# rl rotation
if balance < -1 and ele < node.right.val:
node.right = self.rightRotate(node.right)
return self.leftRotate(node)
return node
# deletion method
def delete(self, node, ele):
if not node:
return node
elif ele < node.val:
node.left = self.delete(node.left, ele)
elif ele > node.val:
node.right = self.delete(node.right, ele)
else:
if node.left is None:
temp = node.right
node = None
return temp
elif node.right is None:
temp = node.left
node = None
return temp
temp = self.getMinValueNode(node.right)
node.val = temp.val
node.right = self.delete(node.right, temp.val)
# one node case
if node is None:
return node
# height updation
node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right))
balance = self.getBalance(node)
# ll rotation
if balance > 1 and self.getBalance(node.left) >= 0:
return self.rightRotate(node)
# rr rotation
if balance < -1 and self.getBalance(node.right) <= 0:
return self.leftRotate(node)
# lr rotation
if balance > 1 and self.getBalance(node.left) < 0:
node.left = self.leftRotate(node.left)
return self.rightRotate(node)
# rl rotation
if balance < -1 and self.getBalance(node.right) > 0:
node.right = self.rightRotate(node.right)
return self.leftRotate(node)
return node
def leftRotate(self, n):
x = n.right
y = x.left
# rotation
x.left = n
n.right = y
n.height = 1 + max(self.getHeight(n.left), self.getHeight(n.right))
x.height = 1 + max(self.getHeight(x.left), self.getHeight(x.right))
return x
def rightRotate(self, n):
x = n.left
y = x.right
# rotation
x.right = n
n.left = y
n.height = 1 + max(self.getHeight(n.left), self.getHeight(n.right))
x.height = 1 + max(self.getHeight(x.left), self.getHeight(x.right))
return x
def height(self, node):
if not node:
return 0
return node.height
def balFact(self, node):
if not node:
return 0
return self.getHeight(node.left) - self.getHeight(node.right)
def getMinValueNode(self, node):
if node is None or node.left is None:
return node
return self.getMinValueNode(node.left)
def preOrderTraversal(self, node):
if not node:
return
print("{0} ".format(node.val), end="")
self.preOrder(node.left)
self.preOrder(node.right)
def main():
tree = AvlTree()
root = None
while True:
print("Choose an operation :\n1. INSERTION\n2. DELETION\n3. PREORDER TRAVERSAL\n4. Exit Program")
ch = int(input("\tMAKE YOUR CHOICE : "))
if ch == 1:
ele = int(input("\nEnter the element for insertion : "))
tree.insertNode(root, ele)
elif ch == 2:
ele = int(input("\nEnter the element for deletion : "))
tree.delete(root, ele)
elif ch == 3:
print("\nPREORDER TRAVERSAL :", end=" ")
tree.preOrderTraversal(root)
elif ch == 4:
exit(1)
main()