crazycloudcc@blog:~/notes/binary-search.md — zsh — 80×24
--:--:--···
crazycloudcc@blog:~/notes/binary-search.md$ pwd
/home/crazycloudcc/blog/notes/binary-search.md
> cd ./notes/binary-search.md
// binary-search
cd ../notes
> cat notes/binary-search.md
[2026-Aug-05] wed · 3 min read
difficulty: beginner
// status: published · type: article
// content

Binary Search in C++

Find a value in a sorted array - the loop invariant, the mid-update trap, and a live run in the browser.

Part two of **Runnable Notes** - snippets that run in the browser. **Binary search** finds a value in a sorted array in `O(log n)`: keep a window `[lo, hi]`, test the middle, throw away the half that cannot contain the target, repeat until the window is empty or you hit it.

The loop

bsearch.cpp · binarySearch
1int binarySearch(const std::vector<int>& a, int target) {
2 int lo = 0;
3 int hi = (int)a.size() - 1;
4 while (lo <= hi) {
5 int mid = lo + (hi - lo) / 2;
6 if (a[mid] == target) {
7 return mid;
8 } else if (a[mid] < target) {
9 lo = mid + 1;
10 } else {
11 hi = mid - 1;
12 }
13 }
14 return -1;
15}

The array must be sorted - that is the precondition that makes discarding a half safe.

The mid-update trap

The single most common binary-search bug is not excluding `mid` when narrowing. Use `lo = mid` instead of `lo = mid + 1` and, when the target sits in the upper half of a two-element window, `lo` never advances - the loop never terminates and the playground kills it after 5 seconds:

Narrowing the window
lo = mid + 1;   // mid was tested: skip past it
hi = mid - 1;
// cpp · good

Always shrink strictly past the element you just tested.

Run it

The program reads `n`, then `n` sorted integers, then a `target`, and prints the index (0-based) or `-1`. Run it here:

playground · bsearch.cppopen full →

A run on a 5-element array, searching for `5`:

bsearch.cpp run · total 470ms
toolchain
360ms
compile
70ms
link
35ms
run
5ms
stdout
2

Try it

stdin is `n`, then the array, then the target:

| stdin | expected stdout | |-------|-----------------| | `5` / `1 3 5 7 9` / `5` | `2` | | `5` / `1 3 5 7 9` / `1` | `0` | | `5` / `1 3 5 7 9` / `9` | `4` | | `5` / `1 3 5 7 9` / `6` | `-1` | | `1` / `5` / `5` | `0` |

Next in the series: **Longest Increasing Subsequence** - from `O(n^2)` DP to the `O(n log n)` patience variant.

// related notes
// EOF — binary-search
branch: mainposts: 8encoding: utf-8
template: ccblogtail -f notes© 2026 crazycloudcc