Skip to content

Commit 6a95bf9

Browse files
committed
Merge branch 'master' of git://github.com/Awfifcuihc/Python into Awfifcuihc-master
2 parents 0d5fd4a + 72c217c commit 6a95bf9

File tree

1 file changed

+255
-0
lines changed

1 file changed

+255
-0
lines changed
+255
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
# -*- coding: utf-8 -*-
2+
'''
3+
An auto-balanced binary tree!
4+
'''
5+
import math
6+
import random
7+
class my_queue:
8+
def __init__(self):
9+
self.data = []
10+
self.head = 0
11+
self.tail = 0
12+
def isEmpty(self):
13+
return self.head == self.tail
14+
def push(self,data):
15+
self.data.append(data)
16+
self.tail = self.tail + 1
17+
def pop(self):
18+
ret = self.data[self.head]
19+
self.head = self.head + 1
20+
return ret
21+
def count(self):
22+
return self.tail - self.head
23+
def print(self):
24+
print(self.data)
25+
print("**************")
26+
print(self.data[self.head:self.tail])
27+
28+
class my_node:
29+
def __init__(self,data):
30+
self.data = data
31+
self.left = None
32+
self.right = None
33+
self.height = 1
34+
def getdata(self):
35+
return self.data
36+
def getleft(self):
37+
return self.left
38+
def getright(self):
39+
return self.right
40+
def getheight(self):
41+
return self.height
42+
def setdata(self,data):
43+
self.data = data
44+
return
45+
def setleft(self,node):
46+
self.left = node
47+
return
48+
def setright(self,node):
49+
self.right = node
50+
return
51+
def setheight(self,height):
52+
self.height = height
53+
return
54+
55+
def getheight(node):
56+
if node is None:
57+
return 0
58+
return node.getheight()
59+
60+
def my_max(a,b):
61+
if a > b:
62+
return a
63+
return b
64+
65+
66+
67+
def leftrotation(node):
68+
'''
69+
A B
70+
/ \ / \
71+
B C Bl A
72+
/ \ --> / / \
73+
Bl Br UB Br C
74+
/
75+
UB
76+
77+
UB = unbalanced node
78+
'''
79+
print("left rotation node:",node.getdata())
80+
ret = node.getleft()
81+
node.setleft(ret.getright())
82+
ret.setright(node)
83+
h1 = my_max(getheight(node.getright()),getheight(node.getleft())) + 1
84+
node.setheight(h1)
85+
h2 = my_max(getheight(ret.getright()),getheight(ret.getleft())) + 1
86+
ret.setheight(h2)
87+
return ret
88+
89+
def rightrotation(node):
90+
'''
91+
a mirror symmetry rotation of the leftrotation
92+
'''
93+
print("right rotation node:",node.getdata())
94+
ret = node.getright()
95+
node.setright(ret.getleft())
96+
ret.setleft(node)
97+
h1 = my_max(getheight(node.getright()),getheight(node.getleft())) + 1
98+
node.setheight(h1)
99+
h2 = my_max(getheight(ret.getright()),getheight(ret.getleft())) + 1
100+
ret.setheight(h2)
101+
return ret
102+
103+
def rlrotation(node):
104+
'''
105+
A A Br
106+
/ \ / \ / \
107+
B C RR Br C LR B A
108+
/ \ --> / \ --> / / \
109+
Bl Br B UB Bl UB C
110+
\ /
111+
UB Bl
112+
RR = rightrotation LR = leftrotation
113+
'''
114+
node.setleft(rightrotation(node.getleft()))
115+
return leftrotation(node)
116+
117+
def lrrotation(node):
118+
node.setright(leftrotation(node.getright()))
119+
return rightrotation(node)
120+
121+
122+
def insert_node(node,data):
123+
if node is None:
124+
return my_node(data)
125+
if data < node.getdata():
126+
node.setleft(insert_node(node.getleft(),data))
127+
if getheight(node.getleft()) - getheight(node.getright()) == 2: #an unbalance detected
128+
if data < node.getleft().getdata(): #new node is the left child of the left child
129+
node = leftrotation(node)
130+
else:
131+
node = rlrotation(node) #new node is the right child of the left child
132+
else:
133+
node.setright(insert_node(node.getright(),data))
134+
if getheight(node.getright()) - getheight(node.getleft()) == 2:
135+
if data < node.getright().getdata():
136+
node = lrrotation(node)
137+
else:
138+
node = rightrotation(node)
139+
h1 = my_max(getheight(node.getright()),getheight(node.getleft())) + 1
140+
node.setheight(h1)
141+
return node
142+
143+
def getRightMost(root):
144+
while root.getright() is not None:
145+
root = root.getright()
146+
return root.getdata()
147+
def getLeftMost(root):
148+
while root.getleft() is not None:
149+
root = root.getleft()
150+
return root.getdata()
151+
152+
def del_node(root,data):
153+
if root.getdata() == data:
154+
if root.getleft() is not None and root.getright() is not None:
155+
temp_data = getLeftMost(root.getright())
156+
root.setdata(temp_data)
157+
root.setright(del_node(root.getright(),temp_data))
158+
elif root.getleft() is not None:
159+
root = root.getleft()
160+
else:
161+
root = root.getright()
162+
elif root.getdata() > data:
163+
if root.getleft() is None:
164+
print("No such data")
165+
return root
166+
else:
167+
root.setleft(del_node(root.getleft(),data))
168+
elif root.getdata() < data:
169+
if root.getright() is None:
170+
return root
171+
else:
172+
root.setright(del_node(root.getright(),data))
173+
if root is None:
174+
return root
175+
if getheight(root.getright()) - getheight(root.getleft()) == 2:
176+
if getheight(root.getright().getright()) > getheight(root.getright().getleft()):
177+
root = rightrotation(root)
178+
else:
179+
root = lrrotation(root)
180+
elif getheight(root.getright()) - getheight(root.getleft()) == -2:
181+
if getheight(root.getleft().getleft()) > getheight(root.getleft().getright()):
182+
root = leftrotation(root)
183+
else:
184+
root = rlrotation(root)
185+
height = my_max(getheight(root.getright()),getheight(root.getleft())) + 1
186+
root.setheight(height)
187+
return root
188+
189+
class AVLtree:
190+
def __init__(self):
191+
self.root = None
192+
def getheight(self):
193+
# print("yyy")
194+
return getheight(self.root)
195+
def insert(self,data):
196+
print("insert:"+str(data))
197+
self.root = insert_node(self.root,data)
198+
199+
def del_node(self,data):
200+
print("delete:"+str(data))
201+
if self.root is None:
202+
print("Tree is empty!")
203+
return
204+
self.root = del_node(self.root,data)
205+
def traversale(self): #a level traversale, gives a more intuitive look on the tree
206+
q = my_queue()
207+
q.push(self.root)
208+
layer = self.getheight()
209+
if layer == 0:
210+
return
211+
cnt = 0
212+
while not q.isEmpty():
213+
node = q.pop()
214+
space = " "*int(math.pow(2,layer-1))
215+
print(space,end = "")
216+
if node is None:
217+
print("*",end = "")
218+
q.push(None)
219+
q.push(None)
220+
else:
221+
print(node.getdata(),end = "")
222+
q.push(node.getleft())
223+
q.push(node.getright())
224+
print(space,end = "")
225+
cnt = cnt + 1
226+
for i in range(100):
227+
if cnt == math.pow(2,i) - 1:
228+
layer = layer -1
229+
if layer == 0:
230+
print()
231+
print("*************************************")
232+
return
233+
print()
234+
break
235+
print()
236+
print("*************************************")
237+
return
238+
239+
def test(self):
240+
getheight(None)
241+
print("****")
242+
self.getheight()
243+
if __name__ == "__main__":
244+
t = AVLtree()
245+
t.traversale()
246+
l = list(range(10))
247+
random.shuffle(l)
248+
for i in l:
249+
t.insert(i)
250+
t.traversale()
251+
252+
random.shuffle(l)
253+
for i in l:
254+
t.del_node(i)
255+
t.traversale()

0 commit comments

Comments
 (0)