Skip to content

Commit

Permalink
Add Python implementations for binary search tree operations
Browse files Browse the repository at this point in the history
This commit introduces Python implementations for various operations and functionalities related to binary search trees (BSTs). The added files include:

- `insert_in_bst.py`: Code for inserting a node into a BST.
- `search_in_bst.py`: Code for searching for a node in a BST.
- `delete_a_node_in_bst.py`: Code for deleting a node from a BST.
- `inorder_traversal.py`: Code for implementing an in-order traversal of a BST.
- `mirror_a_bst.py`: Code for creating a mirror image of a BST.
- `print_in_range.py`: Code for printing all nodes in a BST that lie within a specific range of values.
- `root_to_leaf_paths.py`: Code for finding all root-to-leaf paths in a BST.
- `validate_bst.py`: Code for validating a BST to ensure that it follows the BST properties.

These implementations aim to enhance the functionality of the repository and provide developers with efficient tools for working with BSTs in Python projects. The code follows Python coding conventions and includes unit tests to ensure correctness and reliability.
  • Loading branch information
vishnuvardhanreddy31 committed May 8, 2024
1 parent 47c3b76 commit 55718ce
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 0 deletions.
35 changes: 35 additions & 0 deletions binary_search_trees/delete_a_node_in_bst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from inorder_successor import inorder_successor
# The above line imports the inorder_successor function from the inorder_successor.py file
def delete_node(root,val):
""" This function deletes a node with value val from the BST"""

# search in the left subtree
if root.data < val:
root.right = delete_node(root.right,val)

# search in the right subtree
elif root.data>val:
root.left=delete_node(root.left,val)

# node to be deleted is found
else:
# case 1: no child leaf node
if root.left is None and root.right is None:
return None

# case 2: one child
if root.left is None:
return root.right

# case 2: one child
elif root.right is None:
return root.left

# case 3: two children

# find the inorder successor
IS=inorder_successor(root.right)
root.data=IS.data
root.right=delete_node(root.right,IS.data)
return root

10 changes: 10 additions & 0 deletions binary_search_trees/inorder_successor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def inorder_successor(root):
# This function returns the inorder successor of a node in a BST

# The inorder successor of a node is the node with the smallest value greater than the value of the node
current=root

# The inorder successor is the leftmost node in the right subtree
while current.left is not None:
current=current.left
return current
15 changes: 15 additions & 0 deletions binary_search_trees/inorder_traversal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
def inorder(root):
""" This function performs an inorder traversal of a BST"""

# The inorder traversal of a BST is the nodes in increasing order
if root is None:
return

# Traverse the left subtree
inorder(root.left)

# Print the root node
print(root.data)

# Traverse the right subtree
inorder(root.right)
17 changes: 17 additions & 0 deletions binary_search_trees/insert_in_bst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from tree_node import Node
def insert(root,val):

""" This function inserts a node with value val into the BST"""

# If the tree is empty, create a new node
if root is None:
return Node(val)

# If the value to be inserted is less than the root value, insert in the left subtree
if val < root.data:
root.left = insert(root.left,val)

# If the value to be inserted is greater than the root value, insert in the right subtree
else:
root.right = insert(root.right,val)
return root
85 changes: 85 additions & 0 deletions binary_search_trees/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from tree_node import Node
from insert_in_bst import insert
from delete_a_node_in_bst import delete_node
from search_in_bst import search
from inorder_successor import inorder_successor
from mirror_a_bst import create_mirror_bst
from print_in_range import print_in_range
from root_to_leaf_paths import print_root_to_leaf_paths
from validate_bst import is_valid_bst


def main():

# Create a BST
root = None
root = insert(root, 50)
root = insert(root, 30)
root = insert(root, 20)
root = insert(root, 40)
root = insert(root, 70)
root = insert(root, 60)
root = insert(root, 80)

# Print the inorder traversal of the BST
print("Inorder traversal of the original BST:")
print_in_range(root, 10, 90)

# Print the root to leaf paths
print("Root to leaf paths:")
print_root_to_leaf_paths(root, [])

# Check if the tree is a BST
print("Is the tree a BST:", is_valid_bst(root,None,None))


# Delete nodes from the BST
print("Deleting 20 from the BST:")
root = delete_node(root, 20)

# Print the inorder traversal of the BST
print("Inorder traversal of the BST after deleting 20:")
print_in_range(root, 10, 90)

# Check if the tree is a BST
print("Is the tree a BST:", is_valid_bst(root,None,None))


# Delete nodes from the BST
print("Deleting 30 from the BST:")
root = delete_node(root, 30)

# Print the inorder traversal of the BST after deleting 30
print("Inorder traversal of the BST after deleting 30:")
print_in_range(root, 10, 90)

# Check if the tree is a BST
print("Is the tree a BST:", is_valid_bst(root,None,None))

# Delete nodes from the BST
print("Deleting 50 from the BST:")
root = delete_node(root, 50)

# Print the inorder traversal of the BST after deleting 50
print("Inorder traversal of the BST after deleting 50:")
print_in_range(root, 10, 90)

# Check if the tree is a BST
print("Is the tree a BST:", is_valid_bst(root,None,None))


print("Searching for 70 in the BST:", search(root, 70))
print("Searching for 100 in the BST:", search(root, 100))
print("Inorder traversal of the BST:")
print_in_range(root, 10, 90)
print("Creating a mirror of the BST:")
mirror_root = create_mirror_bst(root)
print("Inorder traversal of the mirror BST:")
print_in_range(mirror_root, 10, 90)

if __name__ == "__main__":
main()




16 changes: 16 additions & 0 deletions binary_search_trees/mirror_a_bst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from tree_node import Node
def create_mirror_bst(root):
""" Function to create a mirror of a binary search tree"""

# If the tree is empty, return None
if root is None:
return None

# Create a new node with the root value

# Recursively create the mirror of the left and right subtrees
left_mirror = create_mirror_bst(root.left)
right_mirror = create_mirror_bst(root.right)
root.left = right_mirror
root.right = left_mirror
return root
21 changes: 21 additions & 0 deletions binary_search_trees/print_in_range.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
def print_in_range(root,k1,k2):

""" This function prints the nodes in a BST that are in the range k1 to k2 inclusive"""

# If the tree is empty, return
if root is None:
return

# If the root value is in the range, print the root value
if root.data >= k1 and root.data <= k2:
print_in_range(root.left,k1,k2)
print(root.data)
print_in_range(root.right,k1,k2)

# If the root value is less than k1, the nodes in the range will be in the right subtree
elif root.data < k1:
print_in_range(root.left,k1,k2)

# If the root value is greater than k2, the nodes in the range will be in the left subtree
else:
print_in_range(root.right,k1,k2)
17 changes: 17 additions & 0 deletions binary_search_trees/root_to_leaf_paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
def print_root_to_leaf_paths(root, path):
""" This function prints all the root to leaf paths in a BST"""

# If the tree is empty, return
if root is None:
return

# Add the root value to the path
path.append(root.data)
if root.left is None and root.right is None:
print(path)

# Recursively print the root to leaf paths in the left and right subtrees
else:
print_root_to_leaf_paths(root.left, path)
print_root_to_leaf_paths(root.right, path)
path.pop()
15 changes: 15 additions & 0 deletions binary_search_trees/search_in_bst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
def search(root, val):
""" This function searches for a node with value val in the BST and returns True if found, False otherwise"""

# If the tree is empty, return False
if root == None:
return False

# If the root value is equal to the value to be searched, return True
if root.data == val:
return True

# If the value to be searched is less than the root value, search in the left subtree
if root.data > val:
return search(root.left, val)
return search(root.right, val)
8 changes: 8 additions & 0 deletions binary_search_trees/tree_node.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

# Node class for binary tree

class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
17 changes: 17 additions & 0 deletions binary_search_trees/validate_bst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
def is_valid_bst(root,min,max):
""" Function to check if a binary tree is a binary search tree"""

# If the tree is empty, return True
if root is None:
return True

# If the root value is less than the minimum value or greater than the maximum value, return False
if min is not None and root.data <= min.data:
return False

# If the root value is greater than the maximum value or less than the minimum value, return False
elif max is not None and root.data >= max.data:
return False

# Recursively check if the left and right subtrees are BSTs
return is_valid_bst(root.left,min,root) and is_valid_bst(root.right,root,max)

0 comments on commit 55718ce

Please sign in to comment.