Binary Search in thealgorithms: Duplicate Value Index Selection Uncertainty
0 reputation · 21 Aug 2020, 20:36 UTC
0 reputation · 21 Aug 2020, 20:36 UTC
The binary_search function in thealgorithms is documented to return the index of a matching element in a sorted list. However, when the target value appears multiple times, the algorithm’s recursive implementation does not specify whether it will return the first, last, or any of the duplicate indices. This ambiguity can lead to inconsistent behavior in client code that relies on a deterministic duplicate handling strategy.
Additionally, the recursive approach imposes a maximum recursion depth that may be exceeded on very large input lists, potentially raising RecursionError. The library offers no configuration to switch to an iterative variant or to adjust recursion limits.
Given these uncertainties, the following questions remain unresolved:
34775 reputation · 21 Aug 2020, 21:16 UTC
Assuming the standard recursive binary_search in TheAlgorithms/Python, it returns an arbitrary matching index when duplicates exist—specifically, the first midpoint where array[mid] == target. It does not guarantee the first or last occurrence. Callers who need deterministic behavior should use bisect_left or bisect_right from Python's standard library, or post-process the returned index by scanning left or right. A RecursionError is not a practical risk for in-memory lists because recursion depth grows as O(log n); even a billion-element list needs only about 30 stack frames.
Confirmed by the algorithm's shape: a recursive binary search that returns immediately on equality stops at whichever midpoint satisfies the condition first. That index is deterministic for a given list but arbitrary with respect to duplicate ordering. Confirmed by arithmetic: Python's default recursion limit is 1000, and log2 of any list that fits in memory stays far below that.
Likely but branch-dependent: the exact source in your checkout. TheAlgorithms/Python is an educational repository with multiple ports and contributors. If your branch has been refactored to an iterative loop or a leftmost/rightmost variant, the duplicate behavior changes. Treat the midpoint-return description as the default assumption unless you have inspected your local copy.
bisect_left(arr, target) and verify i < len(arr) and arr[i] == target.bisect_right(arr, target) - 1 and verify i >= 0 and arr[i] == target.while loop or the standard bisect module.Open the binary_search source in your target branch and check whether the equality case returns immediately or continues searching. Then compare its output against the standard library on a sorted list with duplicates:
from bisect import bisect_left, bisect_right
arr = [1, 2, 2, 2, 3]
first = bisect_left(arr, 2) # 1
last = bisect_right(arr, 2) - 1 # 3
print(first, last)
If the repository function returns 2, it is returning an arbitrary midpoint rather than a boundary index.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.