Navigating Boundary Conventions in Binary Search Implementations
The selection of boundary conventions dictates loop termination conditions, pointer arithmetic, and overall robustness in divide-and-conquer search routines. Understanding how to model the search window is essential for avoiding infinite loops and index-out-of-bounds exceptions.
Mathematical Interval Notation
Search spaces are typically defined using standard interval mathematics:
- Inclusive-Inclusive
[a, b]: Both endpoints are valid candidates. - Inclusive-Exclusive
[a, b): The starting index is valid, while the ending index represents the first position outside the search space. - Exclusive-Inclusive
(a, b]: Rarely used in array indexing due to zero-based systems. - Exclusive-Exclusive
(a, b): Generally unsuitable for iterative pointer-based algorithms.
Array implementations predominantly utilize [0, n-1] (closed) or [0, n) (half-open) conventions.
Closed-Interval Strategy [start, stop]
When both boundaries are treated as viable indices, the algorithm continues searching as long as the window contains at least one element.
Pointer Updates:
- After evaluating the middle element, it must be excluded from the next iteration to prevent stagnation.
- If the target exceeds the middle value, advance
starttomiddle + 1. - If the target is smaller, retreat
stoptomiddle - 1.
Termination: The loop halts when start > stop, indicating an empty search window. The final state requires checking whether a match was found during iteration, or returning a fallback value.
Half-Open Interval Strategy [start, stop)
This convention treats start as a valid index and stop as a strict upper bound (often the array length).
Pointer Updates:
- Advancing
startfollowsstart = middle + 1for values smaller than the probe. - Adjsuting the upper bound uses
stop = middlebecausestopis already exclusive. Includingmiddlein the next iteration preserves the half-open property without skipping potential matches.
Termination: Execution stops when start == stop. At this point, the window has collapsed to zero width. The start variable naturally points to either the exact match or the correct insertion coordinate.
Implementation Examples
Standard Search (Closed-Closed)
int locate_value(const std::vector<int>& data, int key) {
int low_idx = 0;
int high_idx = static_cast<int>(data.size()) - 1;
while (low_idx <= high_idx) {
int probe = low_idx + ((high_idx - low_idx) >> 1);
if (data[probe] == key) {
return probe;
}
if (data[probe] < key) {
low_idx = probe + 1;
} else {
high_idx = probe - 1;
}
}
return -1;
}
Insertion Point / Standard Search (Closed-Open)
int determine_position(const std::vector<int>& sequence, int target) {
int begin_ptr = 0;
int end_ptr = static_cast<int>(sequence.size());
while (begin_ptr < end_ptr) {
int pivot = begin_ptr + ((end_ptr - begin_ptr) >> 1);
if (sequence[pivot] < target) {
begin_ptr = pivot + 1;
} else {
end_ptr = pivot;
}
}
return (begin_ptr < sequence.size() && sequence[begin_ptr] == target)
? begin_ptr
: -1;
}
Boundary Update Mechanics Comparison
| Action | Closed-Closed [L, R] |
Closed-Open [L, R) |
|---|---|---|
| Target larger than pivot | L = pivot + 1 |
L = pivot + 1 |
| Target smaller/equal | R = pivot - 1 |
R = pivot |
| Loop condition | L <= R |
L < R |
| Final state | L > R (empty) |
L == R (single point) |
The half-open model aligns naturally with memory layout and iterator ranges found in modern programming languages. It eliminates off-by-one errors when the target exceeds all existing elements, as end_ptr safely points to the array length. Conversely, the closed model offers more intuitive phrasing for mathematical bounds and simplifies certain range-based problems where both endpoints carry semantic weight.
Selecting a convention depends on problem constraints. Index-based lookups in fixed-size buffers often benefit from [0, n) due to direct length mapping. Problems requiring explicit range shrinking or mathematical proofs may favor [0, n-1] for clearer boundary assertions.
Both approaches execute in O(log N) time by halving the search space each step, with O(1) auxiliary memory overhead. The prerequisite remains a strictly monotonic sequence to guarantee correct pivot comparisons and deterministic convergence.