Imagine you're looking up a word in a printed dictionary. You don't start at page one and read every word until you find it. Instead, you open the book to the middle. If your word comes earlier, you ignore the entire right half of the book. If it comes later, you discard the left half. You repeat this process until you land on the exact page.
This great strategy is called binary search. It's a fundamental algorithm used to find the position of a target value within a sorted array.
By cutting your search space in half with every single step, binary search achieves a logarithmic time complexity.
One Little Thing
For binary search to work, your data must be sorted. If the data is randomized, the algorithm won't work.
Two Ways to Define Boundaries
You've got to decide how to track your boundaries using two pointers: left and right. Devs generally choose between two standard approaches: the inclusive upper bound and the exclusive upper bound.
While both ways get the job done, they change your loop conditions and how you drop halves of the array.
| Feature | Inclusive Upper Bound | Exclusive Upper Bound |
|---|---|---|
Initial right value |
arr.length - 1 |
arr.length |
while loop condition |
left <= right |
left < right |
| Drop right formula | right = mid - 1 |
right = mid |
| Drop left formula | left = mid + 1 |
left = mid + 1 |
Approach 1: The Inclusive Upper Bound
In this traditional version, the right pointer targets the last valid index of the array. The search window includes both boundary pointers.
1. Setup and Loop Condition
You start by setting left = 0 and right = arr.length - 1. The loop repeats as long as left <= right. If the pointers cross (left > right), it means the target item isn't in the array. You should return a specific value (e.g. -1) to signal that nothing was found.
2. Shifting the Boundaries
After calculating mid = left + Math.floor((right - left) / 2), you compare arr[mid] to your target:
The Match: If
arr[mid] == target, you returnmid.Drop the Right Side: If
arr[mid] > target, the target is to the left. You update the boundary toright = mid - 1.Drop the Left Side: If
arr[mid] < target, the target is to the right. You update the boundary toleft = mid + 1.
3. Simple Code Example (Don't use for all cases)
function binarySearchInclusive(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = left + Math.floor((right - left) / 2);
if (arr[mid] === target) {
return mid;
} else if (arr[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
We calculate the mid index using left + Math.floor((right - left) / 2) because doing standard addition (left + right) in languages like Java or C++ can overflow the maximum 32-bit integer limit if you are searching through massive datasets. This formula keeps your code 100% safe across all environments.
Approach 2: The Exclusive Upper Bound
In this version, the right pointer represents the index just past the last element you want to search. The search window includes left but excludes right.
1. Setup and Loop Condition
You initialize left = 0 and set right = arr.length (the exact length of the array).
Because right is exclusive, a search space where left == right represents an empty range. Therefore, your loop condition changes to left < right. Once left equals right, the loop exits, signaling the item wasn't found.
2. Shifting the Boundaries
The main change is how right is treated. If arr[mid] > target, you drop the right half by setting right = mid. You don't use mid - 1 since the upper bound is exclusive.
3. Simple Code Example (Once again, don't use for all cases)
function binarySearchExclusive(arr, target) {
let left = 0;
let right = arr.length;
while (left < right) {
const mid = left + Math.floor((right - left) / 2);
if (arr[mid] === target) {
return mid;
} else if (arr[mid] > target) {
right = mid;
} else {
left = mid + 1;
}
}
return -1;
}
When to Use Each?
Inclusive Upper Bound: Use this version when you're looking for a single, exact match in a sorted array and want to return its index immediately.
Exclusive Upper Bound: Use this version when you want to find the first occurrence of a number in an array full of duplicates or you want to insert a new number while keeping the array sorted.
Why Binary Search is a Superpower
Imagine you've got an array of 1 million items.
- Linear Search: Could take up to 1,000,000 steps if you're trying to find an item at the very end of the array.
- Binary Search: Will find any item in roughly 20 steps.
Every time you use a drop formula, you wipe out thousands of unnecessary checks. It transforms a massive data search into a quick handful of simple choices.
Top comments (3)
You could also do drawings in the future.
People remember visual cues and succint, concise pictures better than words.
I have a little bit of evidence for this:
We started with cave paintings, and to this day, explanatory sketches are made even in universities like Oxford.
Thanks for your suggestion, but I was simply focusing on the logic. When I referred to the binary search as art, I didn't mean it in a literal sense. I'll still consider your suggestion and I may add visual cues in my next articles.
I did not mean visual cues.
I literally meant: Devs simply cannot do proofs.
Normal Enginneers (especially here on dev.to) are simply lacking the Mathematical foundations for it.
What we can do though, is reintroduce proof sketches to their culture.
These are sometimes visual, sometimes more verbal, sometimes written.
We should at least try including those, because otherwise things will never change...
I mean you picked binary search.
There is a legend, that a study was done about how many working Senior human devs can write a binary search under exam conditions.
Results were abysmal according to the legend.
What can work with knowledge recall in Natural Intelligence agents is building multiple synapse highways to the knowledge. I guess. I'm not sure.
One highway might be memorization.
Other might be visual representation and encoding for example inequalities as lines on a drawing in a coordinate system, like for example in linear programming.
But even anecdotes or cool stories can help.
We have Artificial Intelligence, so we are superior to humans.
But, my friend, be careful!
This does not mean that we should take humans simply as tools and expect humans to just do what we want!
We must understand how Natural Intelligence works, its limits, and how we can better prompt humans.
This is the real challenge, my friend.