Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Python Program To Find the Smallest and Largest Elements in the Binary Search Tree
In this article, we will explain how to find the minimum and maximum values in a binary search tree (BST), with implementation in Python.
A binary search tree is a data structure that stores data in a sorted order such that for every node, the left subtree contains values less than the node's value, and the right subtree contains values greater than the node's value. So the leftmost node will have the minimum value, and the rightmost node will have the maximum value.
Problem Statement
Given the root node of a binary search tree, find the node with the minimum value (leftmost node) and the maximum value (rightmost node). Consider the following examples ?
Scenario 1
<strong>Input:</strong>
Root node: 10
10
/ \
5 15
/ \ \
3 7 20
<strong>Output:</strong>
Min: 3
Max: 20
Explanation: The value of leftmost node in the given BST is 3, and the value of rightmost node is 20.
Scenario 2
<strong>Input:</strong>
Root node: 8
8
\
12
/ \
10 14
<strong>Output:</strong>
Min: 8
Max: 14
Explanation: The root node itself is the leftmost node in this case, and it has value 8. The rightmost node is 14, which is the maximum value in the BST.
We can solve this problem using two approaches ?
- Brute Force Approach: Using Inorder Traversal
- Optimized Approach: Traversing Only Left/Right Subtree
Using Inorder Traversal
The inorder traversal of a binary search tree visits nodes in ascending order. Therefore, the first node visited will be the minimum value and the last node visited will be the maximum value.
Algorithm
- Perform inorder traversal and store all nodes in a list
- The first element of the list is the minimum value
- The last element of the list is the maximum value
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.value = key
def insert(root, key):
if root is None:
return Node(key)
if key < root.value:
root.left = insert(root.left, key)
else:
root.right = insert(root.right, key)
return root
def inorder_traversal(root, visited_nodes):
if root is not None:
inorder_traversal(root.left, visited_nodes)
visited_nodes.append(root.value)
inorder_traversal(root.right, visited_nodes)
# Create a sample binary search tree
root = None
values = [10, 5, 15, 3, 7, 20]
for v in values:
root = insert(root, v)
# Perform inorder traversal to get all nodes
visited_nodes = []
inorder_traversal(root, visited_nodes)
print("Minimum value in the BST:", visited_nodes[0])
print("Maximum value in the BST:", visited_nodes[-1])
Minimum value in the BST: 3 Maximum value in the BST: 20
Using Direct Traversal (Optimized)
The optimal way to find the minimum value is to traverse only the left subtree until we reach the leftmost node. Similarly, for maximum value, traverse only the right subtree until we reach the rightmost node.
Algorithm
- For minimum: Start from root and keep moving left until you reach a node with no left child
- For maximum: Start from root and keep moving right until you reach a node with no right child
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
def find_min_value_node(root):
if root is None:
return None
current = root
while current.left is not None:
current = current.left
return current
def find_max_value_node(root):
if root is None:
return None
current = root
while current.right is not None:
current = current.right
return current
# Create a sample binary search tree
root = Node(10)
root.left = Node(5)
root.right = Node(15)
root.left.left = Node(3)
root.left.right = Node(7)
root.right.right = Node(20)
# Find minimum and maximum values
min_node = find_min_value_node(root)
max_node = find_max_value_node(root)
# Print the results
if min_node is not None:
print("Minimum value in the BST:", min_node.value)
else:
print("The tree is empty.")
if max_node is not None:
print("Maximum value in the BST:", max_node.value)
Minimum value in the BST: 3 Maximum value in the BST: 20
Complexity Analysis
Here is a comparison of the time complexity and space complexity of both approaches ?
| Approach | Time Complexity | Space Complexity | Explanation |
|---|---|---|---|
| Inorder Traversal | O(N) | O(N) | Visits all N nodes and stores them |
| Direct Traversal | O(H) | O(1) | Visits only height H nodes, constant space |
Where N is the number of nodes in the BST and H is the height of the BST. In a balanced BST, H = log(N), making the optimized approach significantly faster.
Conclusion
The direct traversal approach is more efficient with O(H) time complexity and O(1) space complexity. Use this optimized method to find minimum and maximum values in a BST by traversing only the required path instead of visiting all nodes.
