Skip to content

Instantly share code, notes, and snippets.

@ajhanwar
Last active June 14, 2017 18:26
Show Gist options
  • Save ajhanwar/a47324987b1944a82dfdd5bffa601730 to your computer and use it in GitHub Desktop.
Save ajhanwar/a47324987b1944a82dfdd5bffa601730 to your computer and use it in GitHub Desktop.
A simple implementation of a binary search tree in Python
class BinarySearchTree:
"""
A simple program implementing a Binary Search Tree using only the key values
Node for the BST is implemented as a private class for encapsulation
"""
class __Node:
def __init__(self, key):
self.key, self.left, self.right = key, None, None
def __init__(self):
self.reinit()
def reinit(self):
self.__root = None
def is_empty(self):
return self.__root is None
def insert(self, key):
if self.__root:
try:
self.__insert_helper(key, self.__root)
except KeyError:
print("Duplicate key:", key)
else:
self.__root = self.__Node(key)
def __insert_helper(self, key, current_node):
if current_node.key == key:
raise KeyError
elif key < current_node.key:
if current_node.left and current_node.key is None:
current_node.left.key = key
elif current_node.left:
self.__insert_helper(key, current_node.left)
else:
current_node.left = self.__Node(key)
else:
if current_node.right and current_node.key is None:
current_node.right.key = key
elif current_node.right:
self.__insert_helper(key, current_node.right)
else:
current_node.right = self.__Node(key)
def remove(self, key):
try:
self.__remove_helper(key, self.__root)
except KeyError:
print("Key:", key, "does not exist")
def __remove_helper(self, key, current, parent=None):
if key < current.key: # Keep searching to the left
if current.left:
self.__remove_helper(key, current.left, current)
else:
raise KeyError
elif key > current.key: # Keep searching to the right
if current.right:
self.__remove_helper(key, current.right, current)
else:
raise KeyError
else:
if current.left is None and current.right is None:
if parent.left is current:
parent.left = None
else:
parent.right = None
elif current.right is None:
if parent.left is current:
parent.left = current.left
else:
parent.right = current.left
elif current.left is None:
if parent.left is current:
parent.left = current.right
else:
parent.right = current.right
else:
# Finding in-order predecessor
switch = current.left
while switch.right:
parent = switch
switch = switch.right
# Swapping the key value of the predecessor with the node "to be deleted"
# The predecessor may have children to its left. The key values of these nodes
# will be greater than that of the "switch" node
current.key = switch.key
parent.right = switch.left
def pre_order(self):
self.__pre_order_helper(self.__root)
def __pre_order_helper(self, current_node):
if current_node is not None:
print(current_node.key)
self.__pre_order_helper(current_node.left)
self.__pre_order_helper(current_node.right)
def in_order(self):
self.__in_order_helper(self.__root)
def __in_order_helper(self, current_node):
if current_node is not None:
self.__in_order_helper(current_node.left)
print(current_node.key)
self.__in_order_helper(current_node.right)
def post_order(self):
self.__post_order_helper(self.__root)
def __post_order_helper(self, current_node):
if current_node is not None:
self.__post_order_helper(current_node.left)
self.__post_order_helper(current_node.right)
print(current_node.key)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment