Algorithm Search⌘K

Proofs: Fibonacci search

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

Fibonacci search returns the first index of x, or NIL, in at most K - 2 steps 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. Extend AA by A[j]=+∞A[j] = +\infty for j≥nj \ge n; the algorithm never reads these items, because line L6 tests mid<nmid < n first and then acts as if A[mid]≥xA[mid] \ge x. Let ℓ=∣{ j<n:A[j]<x }∣\ell = |\{\, j < n : A[j] < x \,\}| be the lower bound of xx, so 0≤ℓ≤n0 \le \ell \le n and, for every j≥0j \ge 0, A[j]<xA[j] < x exactly when j<ℓj < \ell. The answer is ℓ\ell when ℓ<n\ell < n and A[ℓ]=xA[\ell] = x, and NIL otherwise. Write F0=0F_0 = 0, F1=1F_1 = 1, Fk=Fk−1+Fk−2F_k = F_{k-1} + F_{k-2}.

Line L2. Before each test of line L2, (g,f)=(Fk−1,Fk)(g, f) = (F_{k-1}, F_k) for some k≥1k \ge 1: this holds for (0,1)=(F0,F1)(0, 1) = (F_0, F_1), and the step gives (Fk,Fk+Fk−1)=(Fk,Fk+1)(F_k, F_k + F_{k-1}) = (F_k, F_{k+1}). Since FkF_k grows without bound, the loop stops, at the smallest K≥1K \ge 1 with FK−1≥nF_K - 1 \ge n (for n≥1n \ge 1, the values F1=F2=1F_1 = F_2 = 1 both fail and the first success has K≥3K \ge 3).

The invariant. Before each test of line L4:

  1. (g,f)=(Fk−1,Fk)(g, f) = (F_{k-1}, F_k) for some k≥1k \ge 1;
  2. lo≤ℓ≤lo+f−1lo \le \ell \le lo + f - 1.

At the start lo=0lo = 0 and f−1≥n≥ℓf - 1 \ge n \ge \ell, so both hold with k=Kk = K.

Step. The loop runs when f>1f > 1, that is Fk≥2F_k \ge 2, so k≥3k \ge 3 and g=Fk−1≥1g = F_{k-1} \ge 1. Line L5 gives lo≤mid=lo+Fk−1−1≤lo+f−1lo \le mid = lo + F_{k-1} - 1 \le lo + f - 1.

  • If mid<nmid < n and A[mid]<xA[mid] < x, then mid<ℓmid < \ell, so the new lo′=mid+1≤ℓlo' = mid + 1 \le \ell. The new end is lo′+Fk−2−1=lo+Fk−1+Fk−2−1=lo+f−1≥ℓlo' + F_{k-2} - 1 = lo + F_{k-1} + F_{k-2} - 1 = lo + f - 1 \ge \ell. The new pair is (f−g,2g−f)=(Fk−2,Fk−1−Fk−2)=(Fk−2,Fk−3)(f - g, 2g - f) = (F_{k-2}, F_{k-1} - F_{k-2}) = (F_{k-2}, F_{k-3}), and k−2≥1k - 2 \ge 1.
  • Otherwise A[mid]≥xA[mid] \ge x (when mid≥nmid \ge n the extended item is +∞+\infty), so ℓ≤mid=lo+Fk−1−1\ell \le mid = lo + F_{k-1} - 1, which is the new end with the pair (g,f−g)=(Fk−1,Fk−2)(g, f - g) = (F_{k-1}, F_{k-2}), and k−1≥2k - 1 \ge 2.

In both cases statements 1 and 2 hold for the new values.

Termination. Each step lowers kk by 1 or 2 and keeps k≥1k \ge 1, and the loop runs only while k≥3k \ge 3. So it stops after at most K−2K - 2 steps (none when K≤2K \le 2, that is, n=0n = 0). It stops with f≤1f \le 1, so f=Fk=1f = F_k = 1 and statement 2 gives lo≤ℓ≤lolo \le \ell \le lo, so lo=ℓlo = \ell.

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

The number of comparisons. There are at most K−2K - 2 steps, each with at most one comparison, and one more at line L9: at most K−1K - 1. For n≥1n \ge 1, by the choice of KK, FK−1−1<nF_{K-1} - 1 < n, so FK−1≤nF_{K-1} \le n. The bound Fj≥φj−2F_j \ge \varphi^{j-2} for j≥1j \ge 1, with φ=(1+5)/2\varphi = (1 + \sqrt{5})/2, follows by induction from φ2=φ+1\varphi^2 = \varphi + 1. So φK−3≤n\varphi^{K-3} \le n, and the number of steps is K−2≤log⁡φn+1K - 2 \le \log_\varphi n + 1.

Back to Fibonacci search