Re:Binary search with confidence
by orlp on Monday March 07, 2022 @07:16AM
(#30586851)
I am a huge proponent of "bitwise" binary search. Consider r to be the result
index we wish to find in range [0, n), that is, the first index where a
predicate returns false, or n if there is no such predicate. We can construct this index bit-by-bit, starting from
the most significant bit:
I find this to be significantly easier to reason about, although I do have a lot
of experience with bitwise manipulation. And it is trivial to extend to search
a range [lo, hi):
It's similarly trivial to reason they do exactly log2(n) or log2(hi - lo) iterations and are thus worst-case optimal.
[ Parent
| on HN ]
This is called bisection search (search for the largest/smallest value satisfying a given predicate).
It also reminds me a little bit of exponential search (upper bound unknown), although obviously the upper bound is known in your implementation.
Bisection: https://en.wikipedia.org/wiki/Bisection_method Exponential search: https://en.wikipedia.org/wiki/Exponential_search
A practical application of bisection search is in git bisect (https://git-scm.com/docs/git-bisect) to find the first revision that introduced a bug.
Note that with this version, the expected number of calls to `predicate` can be 1 more than strictly necessary (depending on n). This happens when n is one more than a power of 2, e.g. if n is 65 then `bit` is 64 and the first call will be `predicate(64)`, which is basically useless in reducing the search space.