# My Binary Search Tree class BST: """A Binary Search Tree (BST) class.""" def __init__(self, value, parent=None): """Construct a BST. value -- the value of the root node parent -- the parent node (of this BST subtree) """ self.value = value self.left = None self.right = None self.parent = parent def create(a_list): """Create a BST from the elements in a_list.""" bst = BST(a_list[0]) for i in range(1, len(a_list)): bst.insert(a_list[i]) return bst def insert(self, value): """Insert value into the BST.""" if value == self.value: # already in the tree return elif value < self.value: if self.left: self.left.insert(value) else: self.left = BST(value, parent=self) else: if self.right: self.right.insert(value) else: self.right = BST(value, parent=self) def locate(self, value): """Return the node holding value.""" if value == self.value: return self elif value < self.value and self.left: return self.left.locate(value) elif value > self.value and self.right: return self.right.locate(value) else: return None def delete(self, value): """Delete value from the BST.""" node = self.locate(value) if node: node.delete_this_node() def delete_this_node(self): left = self.left right = self.right if left and right: # two children self.delete_with_children() elif left or right: # one child self.delete_with_child() else: # no children self.delete_no_children() def delete_no_children(self): if self.parent: if self.parent.left == self: self.parent.left = None else: self.parent.right = None else: # special case the root node self.value = None def delete_with_child(self): child = self.left if self.left else self.right if self.parent: if self.parent.left == self: self.parent.left = child else: self.parent.right = child child.parent = self.parent else: # special case the root node self.replace(child) def delete_with_children(self): replacement = self.right.min() # the successor successor_value = replacement.value replacement.delete_this_node() # max of one child of this self.value = successor_value def replace(self, other): """Replace this node with the values from other. Also need to reattach other's children. """ self.value = other.value self.left = other.left if self.left: self.left.parent = self self.right = other.right if self.right: self.right.parent = self def min(self): """Returns the left most node of the BST.""" min_node = self while min_node.left: min_node = min_node.left return min_node def inorder(self, function): """Traverse the BST in order performing function.""" if self.left: self.left.inorder(function) function(self.value) if self.right: self.right.inorder(function) def __contains__(self, value): """Does the tree hold the value? So that "in" works.""" if value == self.value: return True elif value < self.value: if self.left: return self.left.__contains__(value) else: return False else: if self.right: return self.right.__contains__(value) else: return False def __str__(self): """Return a string representation of the BST.""" return self._str(0) def _str(self, spaces): string = ' '*spaces + str(self.value) if self.left: string += '\n(l)' + self.left._str(spaces + 4) if self.right: string += '\n(r)' + self.right._str(spaces + 4) return string bst = BST(70) print(bst, '\n') for i in [31, 93, 94, 14, 23, 73]: bst.insert(i) print(bst, '\n') bst.inorder(print) print() for i in [100, 12, 94, 31, 2, 70]: print(i, i in bst) print() print(bst.locate(93)) print(bst.locate(15)) # test deleting bst.delete(70) print(bst, '\n') bst.delete(23) print(bst, '\n') bst.delete(31) print(bst, '\n') bst.delete(73) print(bst, '\n') bst.delete(93) print(bst, '\n') bst.delete(14) print(bst, '\n') bst.delete(94) print(bst, '\n') # This uses a factory method to create the tree. bst = BST.create([17, 5, 35, 2, 11, 29, 38, 9, 16, 8]) print(bst, '\n') bst.delete(16) print(bst, '\n') bst = BST.create([17, 5, 25, 2, 11, 35, 9, 16, 29, 38, 7]) print(bst, '\n') bst.delete(25) print(bst, '\n') #bst = BST.create([33, 23, 40, 17, 32, 51, 9, 28, 45, 76, 26, 80]) #print(bst, '\n') #bst.delete(51) #print(bst, '\n') #bst = BST.create([33, 23, 40, 17, 32, 51, 9, 28, 45, 76, 26, 80]) #bst.delete(26) #print(bst, '\n') #bst = BST.create([33, 23, 40, 17, 32, 51, 9, 28, 45, 76, 26, 80]) #bst.delete(40) #print(bst, '\n') #bst = BST.create([33, 23, 40, 17, 32, 51, 9, 28, 45, 76, 26, 80]) #bst.delete(33) #print(bst, '\n')