11'''
22A binary search Tree
33'''
4-
54class Node :
65
7- def __init__ (self , label ):
6+ def __init__ (self , label , parent ):
87 self .label = label
98 self .left = None
109 self .right = None
10+ #Added in order to delete a node easier
11+ self .parent = parent
1112
1213 def getLabel (self ):
1314 return self .label
@@ -27,6 +28,11 @@ def getRight(self):
2728 def setRight (self , right ):
2829 self .right = right
2930
31+ def getParent (self ):
32+ return self .parent
33+
34+ def setParent (self , parent ):
35+ self .parent = parent
3036
3137class BinarySearchTree :
3238
@@ -35,13 +41,12 @@ def __init__(self):
3541
3642 def insert (self , label ):
3743 # Create a new Node
38- new_node = Node (label )
44+ new_node = Node (label , None )
3945 # If Tree is empty
4046 if self .empty ():
4147 self .root = new_node
4248 else :
4349 #If Tree is not empty
44- parent_node = None
4550 curr_node = self .root
4651 #While we don't get to a leaf
4752 while curr_node is not None :
@@ -58,7 +63,34 @@ def insert(self, label):
5863 if new_node .getLabel () < parent_node .getLabel ():
5964 parent_node .setLeft (new_node )
6065 else :
61- parent_node .setRight (new_node )
66+ parent_node .setRight (new_node )
67+ #Set parent to the new node
68+ new_node .setParent (parent_node )
69+
70+ def delete (self , label ):
71+ if (not self .empty ()):
72+ #Look for the node with that label
73+ node = self .getNode (label )
74+ #If the node exists
75+ if (node is not None ):
76+ #If it has no children
77+ if (node .getLeft () is None and node .getRight () is None ):
78+ self .__reassignNodes (node , None )
79+ node = None
80+ #Has only right children
81+ elif (node .getLeft () is None and node .getRight () is not None ):
82+ self .__reassignNodes (node , node .getRight ())
83+ #Has only left children
84+ elif (node .getLeft () is not None and node .getRight () is None ):
85+ self .__reassignNodes (node , node .getLeft ())
86+ #Has two children
87+ else :
88+ #Gets the max value of the left branch
89+ tmpNode = self .getMax (node .getLeft ())
90+ #Deletes the tmpNode
91+ self .delete (tmpNode .getLabel ())
92+ #Assigns the value to the node to delete and keesp tree structure
93+ node .setLabel (tmpNode .getLabel ())
6294
6395 def getNode (self , label ):
6496 curr_node = None
@@ -78,45 +110,121 @@ def getNode(self, label):
78110 curr_node = curr_node .getRight ()
79111 return curr_node
80112
113+ def getMax (self , root = None ):
114+ if (root is not None ):
115+ curr_node = root
116+ else :
117+ #We go deep on the right branch
118+ curr_node = self .getRoot ()
119+ if (not self .empty ()):
120+ while (curr_node .getRight () is not None ):
121+ curr_node = curr_node .getRight ()
122+ return curr_node
123+
124+ def getMin (self , root = None ):
125+ if (root is not None ):
126+ curr_node = root
127+ else :
128+ #We go deep on the left branch
129+ curr_node = self .getRoot ()
130+ if (not self .empty ()):
131+ curr_node = self .getRoot ()
132+ while (curr_node .getLeft () is not None ):
133+ curr_node = curr_node .getLeft ()
134+ return curr_node
135+
81136 def empty (self ):
82137 if self .root is None :
83138 return True
84139 return False
85140
86- def preShow (self , curr_node ):
141+ def __InOrderTraversal (self , curr_node ):
142+ nodeList = []
87143 if curr_node is not None :
88- print (curr_node .getLabel ())
89- self .preShow (curr_node .getLeft ())
90- self .preShow (curr_node .getRight ())
144+ nodeList .insert (0 , curr_node )
145+ nodeList = nodeList + self .__InOrderTraversal (curr_node .getLeft ())
146+ nodeList = nodeList + self .__InOrderTraversal (curr_node .getRight ())
147+ return nodeList
91148
92149 def getRoot (self ):
93150 return self .root
94151
95- '''
96- Example
97- 8
98- / \
99- 3 10
100- / \ \
101- 1 6 14
102- / \ /
103- 4 7 13
104- '''
152+ def __isRightChildren (self , node ):
153+ if (node == node .getParent ().getRight ()):
154+ return True
155+ return False
105156
157+ def __reassignNodes (self , node , newChildren ):
158+ if (newChildren is not None ):
159+ newChildren .setParent (node .getParent ())
160+ if (node .getParent () is not None ):
161+ #If it is the Right Children
162+ if (self .__isRightChildren (node )):
163+ node .getParent ().setRight (newChildren )
164+ else :
165+ #Else it is the left children
166+ node .getParent ().setLeft (newChildren )
106167
107- if __name__ == "__main__" :
168+ #This function traversal the tree. By default it returns an
169+ #In order traversal list. You can pass a function to traversal
170+ #The tree as needed by client code
171+ def traversalTree (self , traversalFunction = None , root = None ):
172+ if (traversalFunction is None ):
173+ #Returns a list of nodes in preOrder by default
174+ return self .__InOrderTraversal (self .root )
175+ else :
176+ #Returns a list of nodes in the order that the users wants to
177+ return traversalFunction (self .root )
178+
179+ #Returns an string of all the nodes labels in the list
180+ #In Order Traversal
181+ def __str__ (self ):
182+ list = self .__InOrderTraversal (self .root )
183+ str = ""
184+ for x in list :
185+ str = str + " " + x .getLabel ().__str__ ()
186+ return str
187+
188+ def InPreOrder (curr_node ):
189+ nodeList = []
190+ if curr_node is not None :
191+ nodeList = nodeList + InPreOrder (curr_node .getLeft ())
192+ nodeList .insert (0 , curr_node .getLabel ())
193+ nodeList = nodeList + InPreOrder (curr_node .getRight ())
194+ return nodeList
195+
196+ def testBinarySearchTree ():
197+ '''
198+ Example
199+ 8
200+ / \
201+ 3 10
202+ / \ \
203+ 1 6 14
204+ / \ /
205+ 4 7 13
206+ '''
207+
208+ '''
209+ Example After Deletion
210+ 7
211+ / \
212+ 1 4
213+
214+ '''
108215 t = BinarySearchTree ()
109216 t .insert (8 )
110217 t .insert (3 )
111- t .insert (1 )
112218 t .insert (6 )
113- t .insert (4 )
114- t .insert (7 )
219+ t .insert (1 )
115220 t .insert (10 )
116221 t .insert (14 )
117222 t .insert (13 )
223+ t .insert (4 )
224+ t .insert (7 )
118225
119- t .preShow (t .getRoot ())
226+ #Prints all the elements of the list in order traversal
227+ print (t .__str__ ())
120228
121229 if (t .getNode (6 ) is not None ):
122230 print ("The label 6 exists" )
@@ -128,3 +236,22 @@ def getRoot(self):
128236 else :
129237 print ("The label -1 doesn't exist" )
130238
239+ if (not t .empty ()):
240+ print ("Max Value: " , t .getMax ().getLabel ())
241+ print ("Min Value: " , t .getMin ().getLabel ())
242+
243+ t .delete (13 )
244+ t .delete (10 )
245+ t .delete (8 )
246+ t .delete (3 )
247+ t .delete (6 )
248+ t .delete (14 )
249+
250+ #Gets all the elements of the tree In pre order
251+ #And it prints them
252+ list = t .traversalTree (InPreOrder , t .root )
253+ for x in list :
254+ print (x )
255+
256+ if __name__ == "__main__" :
257+ testBinarySearchTree ()
0 commit comments