In the previous article, we explored the binary search algorithm and wrote pseudocode for both iterative and recursive approaches. Now, it’s time to bring that pseudocode to life by implementing binary search in Python. By the end of this article, you’ll have a working implementation of binary search and a clear understanding of how to use it in your programs.
Prerequisites:
- Introduction to binary search for beginners
- Binary Search Algorithm: Step-by-Step Explanation and Visualization
- Binary Search Algorithm: Pseudocode and Explanation
Iterative Implementation of Binary Search in Python
Here’s the Python code for the iterative implementation of binary search algorithm:
def binary_search_iterative(arr, target):
# Initialize the search boundaries
low = 0 # First index
high = len(arr) - 1 # Last index
# Keep searching while we have a valid search space
while low <= high:
# Find the middle element
mid = (low + high) // 2
# Check if we found the target
if arr[mid] == target:
return mid # Target found! Return its index
# If not found, eliminate half the search space
elif arr[mid] < target:
# Target is larger, ignore left half
low = mid + 1
else:
# Target is smaller, ignore right half
high = mid - 1
# If we get here, target wasn't found
return -1
Explanation
- Initialization: Start with
low
at the beginning of the list andhigh
at the end. - Loop: Continue searching as long as
low
is less than or equal tohigh
. - Middle Element: Calculate
mid
and comparearr[mid]
with the target. - Update Pointers: Adjust
low
orhigh
based on the comparison. - Return: If the target is found, return its index. Otherwise, return
-1
.
Example Usage
arr = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
target = 23
result = binary_search_iterative(arr, target)
if result != -1:
print(f"Target found at index {result}.")
else:
print("Target not found.")
Output:
Target found at index 5.
Recursive Implementation of Binary Search in Python
Here’s the Python code for the recursive implementation of binary search algorithm:
def binary_search_recursive(arr, target, low, high):
# Base case 1: There is no search space left
# Which means the target element is not found
if low > high:
return -1
# Find middle point
mid = (low + high) // 2
# Base case 2: Found the target!
if arr[mid] == target:
return mid
# Recursive case 1: Search right half
elif arr[mid] < target:
return binary_search_recursive(arr, target, mid + 1, high)
# Recursive case 2: Search left half
else:
return binary_search_recursive(arr, target, low, mid - 1)
# Helper function to make it easier to use
def binary_search(arr, target):
return binary_search_recursive(arr, target, 0, len(arr) - 1)
Explanation
- Base Case: If
low
exceedshigh
, the target is not in the list. - Middle Element: Calculate
mid
and comparearr[mid]
with the target. - Recursive Calls:
- If the target is greater than
arr[mid]
, search the right half of current search space. - If the target is less than
arr[mid]
, search the left half of current search space.
- If the target is greater than
- Return: If the target is found, return its index. Otherwise, propagate the
-1
from the base case.
Example Usage
arr = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
target = 23
result = binary_search_recursive(arr, target, 0, len(arr) - 1)
if result != -1:
print(f"Target found at index {result}.")
else:
print("Target not found.")
Output:
Target found at index 5.
Binary Search for Descending Order Lists
So far, we’ve implemented binary search for lists sorted in ascending order. But what if our list is sorted in descending order? Let’s explore the changes we need to make to our binary search implementations to handle this case.
Changes in the Algorithm
The core logic of binary search remains the same, but we need to adjust our comparisons:
- When
arr[mid] < target
, we now search the left half (instead of right). - When
arr[mid] > target
, we now search the right half (instead of left).
Iterative Implementation for Descending Order
Here’s how we can modify our iterative implementation:
def binary_search_iterative_desc(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
high = mid - 1 # Search left half
else:
low = mid + 1 # Search right half
return -1
Recursive Implementation for Descending Order
Similarly, we can adjust our recursive implementation:
def binary_search_recursive_desc(arr, target, low, high):
if low > high:
return -1
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
return binary_search_recursive_desc(arr, target, low, mid - 1)
else:
return binary_search_recursive_desc(arr, target, mid + 1, high)
Example Usage
arr_desc = [91, 72, 56, 38, 23, 16, 12, 8, 5, 2]
target = 23
result = binary_search_iterative_desc(arr_desc, target)
if result != -1:
print(f"Target found at index {result}.")
else:
print("Target not found.")
Output:
Target found at index 4.