def _find_smallest_and_parent(self, start_node): """ (BST) -> (BinTreeNode, BinTreeNode) Return a node with the smallest value in the sub-tree rooted at start_node, plus its parent. REQ: start_node != None """ # finding smallest is same as finding left most curr = start_node parent = None while curr.left != None: parent = curr curr = curr.left return (curr, parent) def delete(self, value): """ (BST, str) -> NoneType Delete a node whose data is value from this BST. The BST is unchanged if it does not contain a node whose data is value. """ (del_node, del_parent) = self._find(value) # if there is a node to delete if del_node != None: # if node to delete has no left child if del_node.left == None: # if node to delete is root if del_parent == None: self._root = del_node.right # elif node to delete is a left child elif del_parent.left == del_node: del_parent.left = del_node.right # else node to delete must be a right child else: del_parent.right = del_node.right # elif node to delete has no right child elif del_node.right == None: # if node to delete is root if del_parent == None: self._root = del_node.left # elif node to delete is a left child elif del_parent.left == del_node: del_parent.left = del_node.left # else node to delete must be a right child else: del_parent.right = del_node.left # else node to delete has both left and right children else: # find node with next bigger value (next_bigger, next_parent) = self._find_smallest_and_parent(del_node.right) # copy data from next bigger node to node to delete del_node.data = next_bigger.data # delete next bigger node # if next biggest node is right child of node to delete if next_parent == None: del_node.right = next_bigger.right else: next_parent.left = next_bigger.right