11class AVLTree :
2+
3+ # tree node class
24 class Node :
35 def __init__ (self , val , left = None , right = None ):
46 self .val = val
57 self .left = left
68 self .right = right
79
10+ # function for rotate right at given node
811 def rotate_right (self ):
912 n = self .left
1013 self .val , n .val = n .val , self .val
1114 self .left , n .left , self .right , n .right = n .left , n .right , n , self .right
1215
16+ # function for rotate left at given node
1317 def rotate_left (self ):
1418 n = self .right
1519 self .val , n .val = n .val , self .val
1620 self .right , n .right , self .left , n .left = n .right , n .left , n , self .left
1721
22+ # return the height of the node
1823 @staticmethod
1924 def height (n ):
2025 if not n :
@@ -25,6 +30,7 @@ def __init__(self):
2530 self .root = None
2631 self .size = 0
2732
33+ # return True if value is in the tree, otherwise False
2834 def __contains__ (self , val ):
2935 def contains_rec (node ):
3036 if not node :
@@ -37,16 +43,19 @@ def contains_rec(node):
3743 return True
3844 return contains_rec (self .root )
3945
46+ # return the number of elements in the tree
4047 def __len__ (self ):
4148 return self .size
4249
50+ # return the height of the tree
4351 def height (self ):
4452 def height_rec (t ):
4553 if not t :
4654 return 0
4755 return max (1 + height_rec (t .left ), 1 + height_rec (t .right ))
4856 return height_rec (self .root )
4957
58+ # function for balancing the tree
5059 @staticmethod
5160 def rebalance (t ):
5261 if AVLTree .Node .height (t .left ) > AVLTree .Node .height (t .right ):
@@ -66,6 +75,7 @@ def rebalance(t):
6675 t .right .rotate_right ()
6776 t .rotate_left ()
6877
78+ # function for adding values to the tree
6979 def add (self , val ):
7080 assert val not in self
7181 def add_rec (node ):
@@ -81,6 +91,7 @@ def add_rec(node):
8191 self .root = add_rec (self .root )
8292 self .size += 1
8393
94+ # function for deleting values from the tree
8495 def __delitem__ (self , val ):
8596 assert val in self
8697 def delitem_rec (node ):
@@ -115,3 +126,59 @@ def delitem_rec(node):
115126
116127 self .root = delitem_rec (self .root )
117128 self .size -= 1
129+
130+ # function for printing the tree
131+ def pprint (self , width = 64 ):
132+ height = self .height ()
133+ nodes = [(self .root , 0 )]
134+ prev_level = 0
135+ repr_str = ''
136+ while nodes :
137+ n , level = nodes .pop (0 )
138+ if prev_level != level :
139+ prev_level = level
140+ repr_str += '\n '
141+ if not n :
142+ if level < height - 1 :
143+ nodes .extend ([(None , level + 1 ), (None , level + 1 )])
144+ repr_str += '{val:^{width}}' .format (val = '-' , width = width // 2 ** level )
145+ elif n :
146+ if n .left or level < height - 1 :
147+ nodes .append ((n .left , level + 1 ))
148+ if n .right or level < height - 1 :
149+ nodes .append ((n .right , level + 1 ))
150+ repr_str += '{val:^{width}}' .format (val = n .val , width = width // 2 ** level )
151+ print (repr_str )
152+
153+ if __name__ == "__main__" :
154+
155+ # creating new tree
156+ tree = AVLTree ()
157+
158+ # adding elements to the tree
159+ while True :
160+ x = input ("Enter value to add to the tree or 'q' to quit: " )
161+ if x == 'q' :
162+ break
163+
164+ if int (x ) in tree :
165+ print (f"{ x } is already in the tree" )
166+ else :
167+ tree .add (int (x ))
168+
169+ # print the tree
170+ tree .pprint ()
171+
172+ # remove elements in the tree
173+ while True :
174+ x = input ("Enter value to remove from the tree or 'q' to quit: " )
175+ if x == 'q' :
176+ break
177+
178+ if int (x ) not in tree :
179+ print (f"{ x } is not in the tree" )
180+ else :
181+ tree .__delitem__ (int (x ))
182+
183+ # print the tree
184+ tree .pprint ()
0 commit comments