@@ -28,9 +28,9 @@ def height(self):
2828 downward path from this node to a descendant leaf node).
2929 Best case running time: O(1) if tree is empty
3030 Worst case running time: O(n) if the tree is on one long branch"""
31- right_height , left_height = 0
31+ right_height , left_height = 0 , 0
3232 # base case
33- if self .is_leaf :
33+ if self .is_leaf () :
3434 return 0
3535 if self .right :
3636 right_height = self .right .height () # use ternary
@@ -64,6 +64,9 @@ def height(self):
6464 # Check if root node has a value and if so calculate its height
6565 if self .root :
6666 return self .root .height ()
67+ else :
68+ return 0
69+
6770
6871 def contains (self , item ):
6972 """Return True if this binary search tree contains the given item.
@@ -113,11 +116,75 @@ def insert(self, item):
113116 # Increase the tree size
114117 self .size += 1
115118
119+ # swaps two nodes
120+ def swap (self , a , b ):
121+ # swap data
122+ a_data = a .data
123+ b_data = b .data
124+ a .data = b_data
125+ b .data = a_data
126+ # swap child pointers
127+ a_left = a .left
128+ a_right = a .right
129+ a .left = b .left
130+ a .right = b .right
131+ b .left = a_left
132+ b .right = a_right
133+
134+ def _find_successor (self , node ):
135+ # find the leftmost node in the right subtree
136+ if node .right :
137+ current = node .right
138+ while current .left :
139+ current = current .left
140+ return current
141+
142+ def _find_predecessor (self , node ):
143+ if node .left :
144+ current = node .left
145+ while current .right :
146+ current = current .right
147+ return current .right
148+
116149 def delete (self , item ):
117- found = self .search (item )
118- if found :
150+ found = self ._find_node_recursive (item )
151+ if found is not None : # only attempt to delete if the element is present
119152 parent = self ._find_parent_node (item )
120153
154+ # Case 1: node to be removed has no children
155+ if not found .left and not found .right :
156+ if self .root is found :
157+ self .root = None
158+ else :
159+ if parent .right is found :
160+ parent .right = None
161+ elif parent .left is found :
162+ parent .left = None
163+ # Case 2: node to be removed has one child
164+ if found .right and not found .left : # node to remove has only right child
165+ if found is self .root : # node to remove is root
166+ self .root = found .right
167+ else :
168+ if parent .right is found : # node to remove is right child
169+ parent .right = found .right
170+ if parent .left is found : # node to remove is left child
171+ parent .left = found .right
172+ if found .left and not found .right : # node to remove has only left child
173+ if found is self .root : # node to remove is root
174+ self .root = found .left
175+ else :
176+ if parent .right is found : # node to remove is right child
177+ parent .right = found .left
178+ if parent .left is found : # node to remove is left child
179+ parent .left = found .left
180+
181+ # Case 3: node to be removed has three children
182+ # First find the successor (or predecessor) of the this node.
183+ # Delete the successor (or predecessor) from the tree.
184+ # Replace the node to be deleted with the successor (or predecessor)
185+
186+
187+
121188 def _find_node_iterative (self , item ):
122189 """Return the node containing the given item in this binary search tree,
123190 or None if the given item is not found.
0 commit comments