class Node(object):
def __init__(self, val):
self.val = val
self.left_child = None
self.right_child = None
def insert(self, val):
"""For inserting the value in the Tree"""
if self.val == val:
return False # A BST cannot contain duplicate data
elif val < self.val:
"""Values less than the root data are placed to the left of the root"""
if self.left_child:
return self.left_child.insert(val)
else:
self.left_child = Node(val)
return True
else:
"""Values greater than the root data are placed to the right of the root"""
if self.right_child:
return self.right_child.insert(val)
else:
self.right_child = Node(val)
return True
def min_node(self, node):
current = node
# Find the leftmost leaf
while current.left_child is not None:
current = current.left_child
return current
def max_node(self, node):
current = node
# Find the leftmost leaf
while current.right_child is not None:
current = current.right_child
return current
def delete(self, val, root):
"""For deleting the node"""
if self is None:
return None
# If current node's data is less than that of root node,
# then only search in left subtree, otherwise search in right subtree
if val < self.val:
self.left_child = self.left_child.delete(val, root)
elif val > self.val:
self.right_child = self.right_child.delete(val, root)
else:
# Deleting node with one child
if self.left_child is None:
if self == root:
temp = self.min_node(self.right_child)
self.val = temp.val
self.right_child = self.right_child.delete(temp.val, root)
temp = self.right_child
self = None
return temp
elif self.right_child is None:
if self == root:
temp = self.max_node(self.left_child)
self.val = temp.val
self.left_child = self.left_child.delete(temp.val, root)
temp = self.left_child
self = None
return temp
# Deleting node with two children
# First get the in-order successor
temp = self.min_node(self.right_child)
self.val = temp.val
self.right_child = self.right_child.delete(temp.val, root)
return self
def find(self, val):
"""This function checks whether the specified val is in tree or not"""
if val == self.val:
return True
elif val < self.val:
if self.left_child:
return self.left_child.find(val)
else:
return False
else:
if self.right_child:
return self.right_child.find(val)
else:
return False
def preorder(self):
"""For preorder traversal of the BST"""
if self:
print(str(self.val), end=" ")
if self.left_child:
self.left_child.preorder()
if self.right_child:
self.right_child.preorder()
def inorder(self):
"""For Inorder traversal of the BST"""
if self:
if self.left_child:
self.left_child.inorder()
print(str(self.val), end=" ")
if self.right_child:
self.right_child.inorder()
def postorder(self):
"""For postorder traversal of the BST"""
if self:
if self.left_child:
self.left_child.postorder()
if self.right_child:
self.right_child.postorder()
print(str(self.val), end=" ")
class Tree(object):
def __init__(self):
self.root = None
def insert(self, val):
if self.root:
return self.root.insert(val)
else:
self.root = Node(val)
return True
def delete(self, val):
if self.root is not None:
return self.root.delete(val, self.root)
def find(self, val):
if self.root:
return self.root.find(val)
else:
return False
def preorder(self):
if self.root is not None:
print()
print("Preorder: ")
self.root.preorder()
def inorder(self):
print()
if self.root is not None:
print("Inorder: ")
self.root.inorder()
def postorder(self):
print()
if self.root is not None:
print("Postorder: ")
self.root.postorder()
if __name__ == "__main__":
tree = Tree()
tree.insert(11)
tree.insert(9)
tree.insert(6)
tree.insert(3)
tree.insert(17)
tree.insert(5)
tree.insert(4)
tree.insert(19)
tree.insert(12)
print(tree.find(13))
print(tree.find(5))
""" The following tree is generated:
11
/ \
6 9
/ \
3 17
\ / \
5 12 19
/
4
"""
tree.preorder()
tree.inorder()
tree.postorder()
print("\n\nAfter deleting 19")
tree.delete(19)
tree.inorder()
tree.preorder()
print("\n\nAfter deleting 12")
tree.delete(12)
tree.inorder()
tree.preorder()