Skip to content

Commit 55718ce

Browse files
Add Python implementations for binary search tree operations
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.
1 parent 47c3b76 commit 55718ce

11 files changed

+256
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from inorder_successor import inorder_successor
2+
# The above line imports the inorder_successor function from the inorder_successor.py file
3+
def delete_node(root,val):
4+
""" This function deletes a node with value val from the BST"""
5+
6+
# search in the left subtree
7+
if root.data < val:
8+
root.right = delete_node(root.right,val)
9+
10+
# search in the right subtree
11+
elif root.data>val:
12+
root.left=delete_node(root.left,val)
13+
14+
# node to be deleted is found
15+
else:
16+
# case 1: no child leaf node
17+
if root.left is None and root.right is None:
18+
return None
19+
20+
# case 2: one child
21+
if root.left is None:
22+
return root.right
23+
24+
# case 2: one child
25+
elif root.right is None:
26+
return root.left
27+
28+
# case 3: two children
29+
30+
# find the inorder successor
31+
IS=inorder_successor(root.right)
32+
root.data=IS.data
33+
root.right=delete_node(root.right,IS.data)
34+
return root
35+
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def inorder_successor(root):
2+
# This function returns the inorder successor of a node in a BST
3+
4+
# The inorder successor of a node is the node with the smallest value greater than the value of the node
5+
current=root
6+
7+
# The inorder successor is the leftmost node in the right subtree
8+
while current.left is not None:
9+
current=current.left
10+
return current
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
def inorder(root):
2+
""" This function performs an inorder traversal of a BST"""
3+
4+
# The inorder traversal of a BST is the nodes in increasing order
5+
if root is None:
6+
return
7+
8+
# Traverse the left subtree
9+
inorder(root.left)
10+
11+
# Print the root node
12+
print(root.data)
13+
14+
# Traverse the right subtree
15+
inorder(root.right)

binary_search_trees/insert_in_bst.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from tree_node import Node
2+
def insert(root,val):
3+
4+
""" This function inserts a node with value val into the BST"""
5+
6+
# If the tree is empty, create a new node
7+
if root is None:
8+
return Node(val)
9+
10+
# If the value to be inserted is less than the root value, insert in the left subtree
11+
if val < root.data:
12+
root.left = insert(root.left,val)
13+
14+
# If the value to be inserted is greater than the root value, insert in the right subtree
15+
else:
16+
root.right = insert(root.right,val)
17+
return root

binary_search_trees/main.py

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from tree_node import Node
2+
from insert_in_bst import insert
3+
from delete_a_node_in_bst import delete_node
4+
from search_in_bst import search
5+
from inorder_successor import inorder_successor
6+
from mirror_a_bst import create_mirror_bst
7+
from print_in_range import print_in_range
8+
from root_to_leaf_paths import print_root_to_leaf_paths
9+
from validate_bst import is_valid_bst
10+
11+
12+
def main():
13+
14+
# Create a BST
15+
root = None
16+
root = insert(root, 50)
17+
root = insert(root, 30)
18+
root = insert(root, 20)
19+
root = insert(root, 40)
20+
root = insert(root, 70)
21+
root = insert(root, 60)
22+
root = insert(root, 80)
23+
24+
# Print the inorder traversal of the BST
25+
print("Inorder traversal of the original BST:")
26+
print_in_range(root, 10, 90)
27+
28+
# Print the root to leaf paths
29+
print("Root to leaf paths:")
30+
print_root_to_leaf_paths(root, [])
31+
32+
# Check if the tree is a BST
33+
print("Is the tree a BST:", is_valid_bst(root,None,None))
34+
35+
36+
# Delete nodes from the BST
37+
print("Deleting 20 from the BST:")
38+
root = delete_node(root, 20)
39+
40+
# Print the inorder traversal of the BST
41+
print("Inorder traversal of the BST after deleting 20:")
42+
print_in_range(root, 10, 90)
43+
44+
# Check if the tree is a BST
45+
print("Is the tree a BST:", is_valid_bst(root,None,None))
46+
47+
48+
# Delete nodes from the BST
49+
print("Deleting 30 from the BST:")
50+
root = delete_node(root, 30)
51+
52+
# Print the inorder traversal of the BST after deleting 30
53+
print("Inorder traversal of the BST after deleting 30:")
54+
print_in_range(root, 10, 90)
55+
56+
# Check if the tree is a BST
57+
print("Is the tree a BST:", is_valid_bst(root,None,None))
58+
59+
# Delete nodes from the BST
60+
print("Deleting 50 from the BST:")
61+
root = delete_node(root, 50)
62+
63+
# Print the inorder traversal of the BST after deleting 50
64+
print("Inorder traversal of the BST after deleting 50:")
65+
print_in_range(root, 10, 90)
66+
67+
# Check if the tree is a BST
68+
print("Is the tree a BST:", is_valid_bst(root,None,None))
69+
70+
71+
print("Searching for 70 in the BST:", search(root, 70))
72+
print("Searching for 100 in the BST:", search(root, 100))
73+
print("Inorder traversal of the BST:")
74+
print_in_range(root, 10, 90)
75+
print("Creating a mirror of the BST:")
76+
mirror_root = create_mirror_bst(root)
77+
print("Inorder traversal of the mirror BST:")
78+
print_in_range(mirror_root, 10, 90)
79+
80+
if __name__ == "__main__":
81+
main()
82+
83+
84+
85+

binary_search_trees/mirror_a_bst.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from tree_node import Node
2+
def create_mirror_bst(root):
3+
""" Function to create a mirror of a binary search tree"""
4+
5+
# If the tree is empty, return None
6+
if root is None:
7+
return None
8+
9+
# Create a new node with the root value
10+
11+
# Recursively create the mirror of the left and right subtrees
12+
left_mirror = create_mirror_bst(root.left)
13+
right_mirror = create_mirror_bst(root.right)
14+
root.left = right_mirror
15+
root.right = left_mirror
16+
return root

binary_search_trees/print_in_range.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
def print_in_range(root,k1,k2):
2+
3+
""" This function prints the nodes in a BST that are in the range k1 to k2 inclusive"""
4+
5+
# If the tree is empty, return
6+
if root is None:
7+
return
8+
9+
# If the root value is in the range, print the root value
10+
if root.data >= k1 and root.data <= k2:
11+
print_in_range(root.left,k1,k2)
12+
print(root.data)
13+
print_in_range(root.right,k1,k2)
14+
15+
# If the root value is less than k1, the nodes in the range will be in the right subtree
16+
elif root.data < k1:
17+
print_in_range(root.left,k1,k2)
18+
19+
# If the root value is greater than k2, the nodes in the range will be in the left subtree
20+
else:
21+
print_in_range(root.right,k1,k2)
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
def print_root_to_leaf_paths(root, path):
2+
""" This function prints all the root to leaf paths in a BST"""
3+
4+
# If the tree is empty, return
5+
if root is None:
6+
return
7+
8+
# Add the root value to the path
9+
path.append(root.data)
10+
if root.left is None and root.right is None:
11+
print(path)
12+
13+
# Recursively print the root to leaf paths in the left and right subtrees
14+
else:
15+
print_root_to_leaf_paths(root.left, path)
16+
print_root_to_leaf_paths(root.right, path)
17+
path.pop()

binary_search_trees/search_in_bst.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
def search(root, val):
2+
""" This function searches for a node with value val in the BST and returns True if found, False otherwise"""
3+
4+
# If the tree is empty, return False
5+
if root == None:
6+
return False
7+
8+
# If the root value is equal to the value to be searched, return True
9+
if root.data == val:
10+
return True
11+
12+
# If the value to be searched is less than the root value, search in the left subtree
13+
if root.data > val:
14+
return search(root.left, val)
15+
return search(root.right, val)

binary_search_trees/tree_node.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
# Node class for binary tree
3+
4+
class Node:
5+
def __init__(self, data):
6+
self.data = data
7+
self.left = None
8+
self.right = None

binary_search_trees/validate_bst.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
def is_valid_bst(root,min,max):
2+
""" Function to check if a binary tree is a binary search tree"""
3+
4+
# If the tree is empty, return True
5+
if root is None:
6+
return True
7+
8+
# If the root value is less than the minimum value or greater than the maximum value, return False
9+
if min is not None and root.data <= min.data:
10+
return False
11+
12+
# If the root value is greater than the maximum value or less than the minimum value, return False
13+
elif max is not None and root.data >= max.data:
14+
return False
15+
16+
# Recursively check if the left and right subtrees are BSTs
17+
return is_valid_bst(root.left,min,root) and is_valid_bst(root.right,root,max)

0 commit comments

Comments
 (0)