-
Notifications
You must be signed in to change notification settings - Fork 0
/
AVL.py
398 lines (385 loc) · 18.8 KB
/
AVL.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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
from BST import NodeBST
from Stack import Stack
class AVL():
def __init__(self):
self.number_of_words =0
self.i = 0
self.root = None
def add(self, node_of_word):
check_balance_nodes = Stack()
current_node = self.root
wordIsAdded = False
if not current_node:
current_node = NodeBST(node_of_word.data.lower())
current_node.refrence.SuperAdd(node_of_word, root_tree=self, node_ref=current_node)
self.root = current_node
wordIsAdded = True
while not wordIsAdded:
if node_of_word.data.lower() > current_node.word:
check_balance_nodes.push(current_node)
if current_node.rightChild == None:
current_node.rightChild = NodeBST(node_of_word.data.lower())
current_node.rightChild.refrence.SuperAdd(node_of_word, root_tree=self,node_ref=current_node.rightChild)
current_node.rightChild.father = current_node
wordIsAdded = True
else:
current_node = current_node.rightChild
elif node_of_word.data.lower() < current_node.word:
check_balance_nodes.push(current_node)
if current_node.leftChild == None:
current_node.leftChild = NodeBST(node_of_word.data.lower())
current_node.leftChild.refrence.SuperAdd(node_of_word, root_tree=self,node_ref=current_node.leftChild)
current_node.leftChild.father = current_node
wordIsAdded = True
else:
current_node = current_node.leftChild
else:
current_node.refrence.SuperAdd(node_of_word, root_tree=self, node_ref=current_node)
wordIsAdded = True
while not check_balance_nodes.isEmpty():
current_checking_node = check_balance_nodes.pop()
height_of_left = self.ret_bf(current_checking_node.leftChild)
height_of_right = self.ret_bf(current_checking_node.rightChild)
if (height_of_left - height_of_right == 2):
if self.ret_bf(current_checking_node.leftChild.rightChild) > self.ret_bf(current_checking_node.leftChild.leftChild):
# LR rotate in AVL
s = current_checking_node.leftChild.rightChild
tmpNode = current_checking_node.leftChild
current_checking_node.leftChild = s.rightChild
tmpNode.rightChild = s.leftChild
if s.rightChild:
s.rightChild.father = current_checking_node
s.rightChild = current_checking_node
if s.leftChild:
s.leftChild.father = tmpNode
s.leftChild = tmpNode
if current_checking_node == self.root:
self.root = s
else:
if check_balance_nodes.peek().leftChild == current_checking_node:
check_balance_nodes.peek().leftChild = s
else:
check_balance_nodes.peek().rightChild = s
s.father = current_checking_node.father
current_checking_node.father = s
tmpNode.father = s
self.balance_factor_cal(tmpNode)
self.balance_factor_cal(s)
self.balance_factor_cal(current_checking_node)
else:
# LL rotate in AVL
tmpNode = current_checking_node.leftChild
current_checking_node.leftChild = tmpNode.rightChild
tmpNode.rightChild = current_checking_node
if current_checking_node == self.root:
self.root = tmpNode
else:
if check_balance_nodes.peek().leftChild == current_checking_node:
check_balance_nodes.peek().leftChild = tmpNode
else:
check_balance_nodes.peek().rightChild = tmpNode
tmpNode.father = current_checking_node.father
current_checking_node.father = tmpNode
if current_checking_node.leftChild:
current_checking_node.leftChild.father = current_checking_node
self.balance_factor_cal(current_checking_node)
self.balance_factor_cal(tmpNode)
elif (height_of_right - height_of_left == 2):
if self.ret_bf(current_checking_node.rightChild.rightChild) > self.ret_bf(current_checking_node.rightChild.leftChild):
# RR rotate in AVL
tmpNode = current_checking_node.rightChild
current_checking_node.rightChild = tmpNode.leftChild
tmpNode.leftChild = current_checking_node
if current_checking_node == self.root:
self.root = tmpNode
else:
if check_balance_nodes.peek().leftChild == current_checking_node:
check_balance_nodes.peek().leftChild = tmpNode
else:
check_balance_nodes.peek().rightChild = tmpNode
tmpNode.father = current_checking_node.father
current_checking_node.father = tmpNode
if current_checking_node.rightChild:
current_checking_node.rightChild.father = current_checking_node
self.balance_factor_cal(current_checking_node)
self.balance_factor_cal(tmpNode)
else:
# RL rotate in AVL
s = current_checking_node.rightChild.leftChild
tmpNode = current_checking_node.rightChild
current_checking_node.rightChild = s.leftChild
tmpNode.leftChild = s.rightChild
if s.leftChild:
s.leftChild.father = current_checking_node
s.leftChild = current_checking_node
if s.rightChild:
s.rightChild.father = tmpNode
s.rightChild = tmpNode
if current_checking_node == self.root:
self.root = s
else:
if check_balance_nodes.peek().leftChild == current_checking_node:
check_balance_nodes.peek().leftChild = s
else:
check_balance_nodes.peek().rightChild = s
s.father = current_checking_node.father
current_checking_node.father = s
tmpNode.father = s
self.balance_factor_cal(tmpNode)
self.balance_factor_cal(s)
self.balance_factor_cal(current_checking_node)
else:
self.balance_factor_cal(current_checking_node)
def get(self, word):
current_node = self.root
while current_node != None:
if word.lower() == current_node.word:
return current_node
if word.lower() > current_node.word:
current_node = current_node.rightChild
else:
current_node = current_node.leftChild
return None
def find_biggest_left_child(self,node):
while node.rightChild:
node = node.rightChild
return node
def find_lowest_right_child(self, node):
while node.leftChild:
node = node.leftChild
return node
def remove(self,node_to_delete,root_of_delete=None):
if root_of_delete == None:
root_of_delete = self.root
isLeft = False
tmp_father = node_to_delete.father
if node_to_delete.father and node_to_delete.father.leftChild == node_to_delete:
isLeft = True
if node_to_delete.leftChild:
if node_to_delete.rightChild:
tmp_node = self.find_lowest_right_child(node_to_delete.rightChild)
self.remove(tmp_node,root_of_delete=node_to_delete)
if node_to_delete.rightChild:
node_to_delete.rightChild.father = tmp_node
node_to_delete.leftChild.father = tmp_node
tmp_node.father = node_to_delete.father
tmp_node.leftChild = node_to_delete.leftChild
tmp_node.rightChild = node_to_delete.rightChild
if node_to_delete == self.root :
self.root = tmp_node
else:
if node_to_delete.father.leftChild == node_to_delete:
node_to_delete.father.leftChild = tmp_node
else:
node_to_delete.father.rightChild = tmp_node
else:
if node_to_delete == self.root:
self.root = node_to_delete.leftChild
else:
node_to_delete.leftChild.father = node_to_delete.father
if node_to_delete.father.leftChild == node_to_delete:
node_to_delete.father.leftChild = node_to_delete.leftChild
else:
node_to_delete.father.rightChild = node_to_delete.leftChild
# node_to_delete.father = None
else :
if node_to_delete.rightChild:
if node_to_delete == self.root:
self.root = node_to_delete.rightChild
else:
node_to_delete.rightChild.father = node_to_delete.father
if node_to_delete.father.leftChild == node_to_delete:
node_to_delete.father.leftChild = node_to_delete.rightChild
else:
node_to_delete.father.rightChild = node_to_delete.rightChild
else:
if node_to_delete == self.root:
self.root = None
else:
if node_to_delete.father.leftChild == node_to_delete:
node_to_delete.father.leftChild = None
else:
node_to_delete.father.rightChild = None
if isLeft:
if tmp_father.leftChild:
checking_balance_node = tmp_father.leftChild
else:
checking_balance_node = tmp_father
else:
if tmp_father and tmp_father.rightChild:
checking_balance_node = tmp_father.rightChild
else:
checking_balance_node = tmp_father
while (checking_balance_node and checking_balance_node != root_of_delete and checking_balance_node) or checking_balance_node == self.root:
tmp_father = checking_balance_node.father
height_of_left = self.ret_bf(checking_balance_node.leftChild)
height_of_right = self.ret_bf(checking_balance_node.rightChild)
if (height_of_left - height_of_right == 2):
if self.ret_bf(checking_balance_node.leftChild.rightChild) > self.ret_bf(checking_balance_node.leftChild.leftChild):
# LR rotate in AVL
s = checking_balance_node.leftChild.rightChild
tmpNode = checking_balance_node.leftChild
checking_balance_node.leftChild = s.rightChild
tmpNode.rightChild = s.leftChild
if s.rightChild:
s.rightChild.father = checking_balance_node
s.rightChild = checking_balance_node
if s.leftChild:
s.leftChild.father = tmpNode
s.leftChild = tmpNode
if checking_balance_node == self.root:
self.root = s
else:
if checking_balance_node.father.leftChild == checking_balance_node:
checking_balance_node.father.leftChild = s
else:
checking_balance_node.father.rightChild = s
s.father = checking_balance_node.father
tmpNode.father = s
checking_balance_node.father = s
self.balance_factor_cal(tmpNode)
self.balance_factor_cal(s)
self.balance_factor_cal(checking_balance_node)
else:
# LL rotate in AVL
tmpNode = checking_balance_node.leftChild
checking_balance_node.leftChild = tmpNode.rightChild
tmpNode.rightChild = checking_balance_node
if checking_balance_node == self.root:
self.root = tmpNode
else:
if checking_balance_node.father.leftChild == checking_balance_node:
checking_balance_node.father.leftChild = tmpNode
else:
checking_balance_node.father.rightChild = tmpNode
tmpNode.father = checking_balance_node.father
checking_balance_node.father = tmpNode
if checking_balance_node.leftChild:
checking_balance_node.leftChild.father = checking_balance_node
self.balance_factor_cal(checking_balance_node)
self.balance_factor_cal(tmpNode)
elif (height_of_right - height_of_left == 2):
if self.ret_bf(checking_balance_node.rightChild.rightChild) > self.ret_bf(checking_balance_node.rightChild.leftChild):
# RR rotate in AVL
tmpNode = checking_balance_node.rightChild
checking_balance_node.rightChild = tmpNode.leftChild
tmpNode.leftChild = checking_balance_node
if checking_balance_node == self.root:
self.root = tmpNode
else:
if checking_balance_node.father.leftChild == checking_balance_node:
checking_balance_node.father.leftChild = tmpNode
else:
checking_balance_node.father.rightChild = tmpNode
tmpNode.father = checking_balance_node.father
checking_balance_node.father = tmpNode
if checking_balance_node.rightChild:
checking_balance_node.rightChild.father = checking_balance_node
self.balance_factor_cal(checking_balance_node)
self.balance_factor_cal(tmpNode)
else:
# RL rotate in AVL
s = checking_balance_node.rightChild.leftChild
tmpNode = checking_balance_node.rightChild
checking_balance_node.rightChild = s.leftChild
tmpNode.leftChild = s.rightChild
if s.leftChild:
s.leftChild.father = checking_balance_node
s.leftChild = checking_balance_node
if s.rightChild:
s.rightChild.father = tmpNode
s.rightChild = tmpNode
if checking_balance_node == self.root:
self.root = s
else:
if checking_balance_node.father.leftChild == checking_balance_node:
checking_balance_node.father.leftChild = s
else:
checking_balance_node.father.rightChild = s
s.father = checking_balance_node.father
tmpNode.father = s
checking_balance_node.father = s
self.balance_factor_cal(tmpNode)
self.balance_factor_cal(s)
self.balance_factor_cal(checking_balance_node)
else:
self.balance_factor_cal(checking_balance_node)
self.balance_factor_cal(checking_balance_node)
checking_balance_node = tmp_father
def traverse(self, node=None):
if node == None:
node = self.root
if node.leftChild != None:
self.traverse(node=node.leftChild)
if node.rightChild != None:
self.traverse(node=node.rightChild)
self.i = self.i + 1
print(self.i.__str__() + ' ' + node.word + node.balance_factor.__str__())
def traverse_words_documents(self, node=None,sentence=''):
if node == None:
node = self.root
if node and node.leftChild != None:
sentence = sentence + self.traverse_words_documents(node=node.leftChild)
if node and node.rightChild != None:
sentence = sentence + self.traverse_words_documents(node=node.rightChild)
if node :
node_documents = node.refrence.getDocuments()
if node_documents is not '':
self.number_of_words = self.number_of_words+1
return sentence + node_documents
else:
return ''
def height(self,node = None,isRoot = True):
if isRoot:
node = self.root
if node == None:
return -1
leftH = self.height(node = node.leftChild,isRoot=False)
rightH = self.height(node = node.rightChild,isRoot=False)
return max(leftH,rightH)+1
def balance_factor_cal(self,node):
result = 0
left_bf = -1
right_bf = -1
if node.leftChild:
left_bf = node.leftChild.balance_factor
if node.rightChild:
right_bf = node.rightChild.balance_factor
node.balance_factor = max(left_bf,right_bf)+1
return node.balance_factor
def ret_bf(self,node):
if not node :
return -1
else:
return node.balance_factor
if __name__ == '__main__':
from LinkedList import Node
alireza = AVL()
alireza.add(Node('m'))
alireza.add(Node('f'))
alireza.add(Node('s'))
alireza.add(Node('b'))
alireza.add(Node('j'))
alireza.add(Node('q'))
alireza.add(Node('u'))
alireza.add(Node('a'))
alireza.add(Node('c'))
alireza.add(Node('g'))
alireza.add(Node('k'))
alireza.add(Node('n'))
alireza.add(Node('r'))
alireza.add(Node('t'))
alireza.add(Node('w'))
# alireza.add(Node('t'))
alireza.traverse()
alireza.remove(alireza.get('s'))
alireza.traverse()
alireza.remove(alireza.get('t'))
alireza.remove(alireza.get('w'))
alireza.traverse()
alireza.remove(alireza.get('u'))
alireza.remove(alireza.get('a'))
alireza.remove(alireza.get('c'))
alireza.remove(alireza.get('r'))
alireza.remove(alireza.get('n'))
alireza.traverse()