Binary Search Trees
Naveen Raja S.M
What is a Tree data structure?
• A Tree is a non-linear data structure and a hierarchy, consisting of a
collection of nodes, such that each node of the tree stores a value and
a list of references to other nodes (the “children”).
Example of Tree data structure
• Binary Tree is defined as a Tree data structure with at most 2 children.
• Since each element in a binary tree can have only 2 children, we
typically name them the left and right child.
Definition: Binary Search Tree
A binary Search Tree is a data structure which has the following
properties:
• The left subtree of a node contains only nodes with keys lesser than
the node’s key.
• The right subtree of a node contains only nodes with keys greater
than the node’s key.
• The left and right subtree each must also be a binary search tree.
• There must be no duplicate nodes.
Binary Search Tree:
1) Implementation: Binary Search Tree
Consider the Following Binary Search Tree:
This binary search tree can be implemented
by creating node structure as follows:
Creating a node
class Binarysearchtree:
def __init__(self,key):
self.key = key
self.lchild = None
self.rchild = None
root = Binarysearchtree(10)
print(root.key)
print(root.lchild)
print(root.rchild)
2. Operations:
• There are three major operations that can be performed in the linked
list.
i) Insertion
ii) Deletion
iii) Searching
iv) Min and Max value
i) Insertion
While inserting a node in a binary search tree, three conditions may
arise.
1.The Binary search tree can be empty. i.e. Root itself will be a value
None.
2.The Value to be inserted is less than the root.
3.The value to be inserted is greater than the root.
• To implement the first condition, we just make a new node and declare
it as root.
• To implement second and third condition, We follow the following
approach.
• From the properties of a binary search tree, we can see that each sub
tree is a binary search tree in itself. Thus we can consider each node as
a root of another binary tree.
• While inserting a new node, if the value of the new data is less than
the value of the current node, we will add it to the left child of the
binary search tree, otherwise, we will add it to the right child.
def insert(self, val): if val < self.val:
if not self.val: if self.left:
self.left.insert(val)
self.val = val return
return self.left = BSTNode(val)
return
if self.val == val: if self.right:
return self.right.insert(val)
return
self.right = BSTNode(val)
ii)Deletion
When we delete a node, three possibilities arise.
1) Node to be deleted is the leaf: Simply remove it from the tree.
2) Node to be deleted has only one child: Copy the child to the node
and delete the child
3) Node to be deleted has two children: Find inorder successor of
the node. Copy contents of the inorder successor to the node and delete
the inorder successor.
Follow the below steps to delete an item
• If the root is NULL, then return root
• If the key is less than the root’s value, then set root->left = deleteNode(root->left, key)
• If the key is greater than the root’s value, then set root->right = deleteNode(root->right,
key)
• Else check
• If the root is a leaf node(don’t have child) then return null
• else if it has only the left child, then return the left child
• else if it has only the right child, then return the right child
• else set the value of root as of its inorder successor and recur to delete the node with the
value of the inorder successor
• Return
def delete(self,data):
if self.key is None:
print("Tree is empty!")
return
if data < self.key:
if self.lchild:
self.lchild = self.lchild.delete(data)
else:
print("Given Node is not present in the tree")
elif data > self.key:
if self.rchild:
self.rchild = self.rchild.delete(data)
else:
print("Given Node is not present in the tree")
else:
if self.lchild is None:
temp = self.rchild
self = None
return temp
if self.rchild is None:
temp = self.lchild
self = None
return temp
node = self.rchild
while node.lchild:
node = node.lchild
self.key = node.key
self.rchild = self.rchild.delete(node.key)
return self
iii)Searching
• Searching means finding specific node within a data structure.
• However, searching for some specific node in binary search tree is pretty easy due
to the fact that, element in BST are stored in a particular order.
1. Compare the element with the root of the tree.
2. If the item is matched then return the location of the node.
3. Otherwise check if item is less than the element present on root, if so then move
to the left sub-tree.
4. If not, then move to the right sub-tree.
5. Repeat this procedure recursively until match found.
6. If element is not found then return NULL.
def search(self,data):
if self.key == data:
print("Node is found")
return
if data < self.key:
if self.lchild:
self.lchild.search(data)
else:
print("Node is not present")
else:
if self.rchild:
self.rchild.search(data)
else:
print("Node is not present")
iv) Min and Max value
Approach for finding minimum element:
• Traverse the node from root to left recursively until left is NULL.
• The node whose left is NULL is the node with minimum value.
Approach for finding maximum element:
• Traverse the node from root to right recursively until right is NULL.
• The node whose right is NULL is the node with maximum value.
Min value
class BST:
def bstmin(self,data):
if data is None:
return None
elif data.left is None:
return data
else:
return self.bstMin(data.left)
Max value
class BST:
def bstmax(self,data):
if data is None:
return None
elif data.right is None:
return data
else:
return self.bstmax(data.right)