Algorithm Search⌘K

Proofs: Exponential search

These are the human proofs of Exponential search, at full length.

Exponential search returns the first index of x, or NIL, with at most 2 floor(lg l) + 3 comparisons full

This proof shows: correctness, termination, complexity.

Let A[0…n−1]A[0 \ldots n-1] be sorted in non-decreasing order, n≥0n \ge 0, and let xx be a key. Let ℓ=∣{ j:A[j]<x }∣\ell = |\{\, j : A[j] < x \,\}| be the lower bound of xx. Because AA is sorted, A[j]<xA[j] < x exactly for j<ℓj < \ell. The copies of xx, if any, are at the indices ℓ,ℓ+1,…\ell, \ell + 1, \ldots, so the answer is ℓ\ell when ℓ<n\ell < n and A[ℓ]=xA[\ell] = x, and NIL otherwise.

The doubling loop. Before each test of line L2:

  1. b=2kb = 2^k for an integer k≥0k \ge 0;
  2. A[j]<xA[j] < x for each j<⌊b/2⌋j < \lfloor b/2 \rfloor, that is, ⌊b/2⌋≤ℓ\lfloor b/2 \rfloor \le \ell;
  3. b≤ℓb \le \ell when b≥2b \ge 2, that is, the test at b/2b/2 passed.

At the start b=1b = 1, ⌊b/2⌋=0\lfloor b/2 \rfloor = 0, and statements 2 and 3 say nothing. A pass runs only when b≤nb \le n and A[b−1]<xA[b - 1] < x, so b−1<ℓb - 1 < \ell and b≤ℓb \le \ell. For the new value b′=2bb' = 2b we get ⌊b′/2⌋=b≤ℓ\lfloor b'/2 \rfloor = b \le \ell, which is statement 2, and statement 3 holds for b′b' as well.

Termination. Each pass doubles bb, and a pass runs only when b≤nb \le n, so there are at most ⌊lg⁡n⌋+1\lfloor \lg n \rfloor + 1 passes when n≥1n \ge 1, and none when n=0n = 0.

Exit. The loop stops when b>nb > n or A[b−1]≥xA[b - 1] \ge x. In the first case ℓ≤n\ell \le n. In the second case b≤nb \le n, and A[b−1]≥xA[b-1] \ge x gives ℓ≤b−1\ell \le b - 1. In both cases ℓ≤min⁡(b−1,n)\ell \le \min(b - 1, n). Line L4 sets lo=⌊b/2⌋lo = \lfloor b/2 \rfloor and hi=min⁡(b−1,n)hi = \min(b - 1, n), so with statement 2,

lo≤ℓ≤hi.lo \le \ell \le hi.

The binary search. Before each test of line L5, lo≤ℓ≤hilo \le \ell \le hi. A pass has lo<hilo < hi, so lo≤mid<hilo \le mid < hi. If A[mid]<xA[mid] < x then mid<ℓmid < \ell and the new lo=mid+1≤ℓlo = mid + 1 \le \ell. Otherwise A[mid]≥xA[mid] \ge x, so ℓ≤mid\ell \le mid, and the new hi=mid≥ℓhi = mid \ge \ell. In both cases the invariant holds and hi−lohi - lo drops by at least 1, since the new size is ⌊(hi−lo)/2⌋\lfloor (hi - lo)/2 \rfloor or ⌈(hi−lo)/2⌉−1\lceil (hi - lo)/2 \rceil - 1. So the loop stops, with lo≥hilo \ge hi, and then lo=ℓ=hilo = \ell = hi.

Result. Line L9 runs with lo=ℓlo = \ell and returns ℓ\ell exactly when ℓ<n\ell < n and A[ℓ]=xA[\ell] = x, which is the answer. Otherwise line L10 returns NIL, which is the answer. ■\blacksquare

The number of comparisons. If ℓ=0\ell = 0 and n≥1n \ge 1, the first test fails, lo=hi=0lo = hi = 0, and with line L9 there are 2 comparisons. If n=0n = 0 there are none.

Let ℓ≥1\ell \ge 1 and k=⌊lg⁡ℓ⌋k = \lfloor \lg \ell \rfloor, so 2k≤ℓ<2k+12^k \le \ell < 2^{k+1}. A test at bb can pass only when b≤ℓb \le \ell, by statement 3 for the next value, so the passes are at b=1,2,…,2jb = 1, 2, \ldots, 2^j with j≤kj \le k, and there is at most one more test, a failing one. So the doubling makes at most k+2k + 2 tests, and it stops with b≤2k+1b \le 2^{k+1}. The interval of line L4 then has s=hi−lo≤b−1−b/2=b/2−1≤2k−1s = hi - lo \le b - 1 - b/2 = b/2 - 1 \le 2^k - 1 positions. The binary search makes at most ⌈lg⁡(s+1)⌉≤k\lceil \lg(s + 1) \rceil \le k tests, because each test leaves at most ⌊s/2⌋\lfloor s/2 \rfloor positions and ⌊(2k−1)/2⌋=2k−1−1\lfloor (2^k - 1)/2 \rfloor = 2^{k-1} - 1. With the one test of line L9 the total is at most (k+2)+k+1=2⌊lg⁡ℓ⌋+3(k + 2) + k + 1 = 2\lfloor \lg \ell \rfloor + 3.

Back to Exponential search