Algorithm Search⌘K

Proofs: Staircase search

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

Staircase search finds x when it occurs, returns NIL otherwise, and reads at most m + n - 1 cells full

This proof shows: correctness, termination, complexity.

Let MM be an m×nm \times n matrix, m,n≥0m, n \ge 0, with M[i][j]≤M[i][j+1]M[i][j] \le M[i][j+1] and M[i][j]≤M[i+1][j]M[i][j] \le M[i+1][j] for all indices in range, and let xx be a key. Write X={(k,l):M[k][l]=x}X = \{(k, l) : M[k][l] = x\} for the set of cells that hold xx. We prove three things about STAIRCASE-SEARCH(M,x)(M, x): it stops after at most m+n−1m + n - 1 passes of the loop, a returned pair is in XX, and NIL is returned only when XX is empty.

Invariant. Before each test of line L2, every (k,l)∈X(k, l) \in X has k≥ik \ge i and l≤jl \le j. Also 0≤i≤m0 \le i \le m and −1≤j≤n−1-1 \le j \le n - 1.

Start. Line L1 sets i=0i = 0 and j=n−1j = n - 1. Every cell has k≥0k \ge 0 and l≤n−1l \le n - 1, so the first statement holds. The bounds hold since m,n≥0m, n \ge 0.

Step. A pass runs only when i<mi < m and j≥0j \ge 0, so (i,j)(i, j) is a cell. If M[i][j]=xM[i][j] = x, line L3 returns. Otherwise there are two cases.

  • Case M[i][j]>xM[i][j] > x. Line L4 sets j′=j−1j' = j - 1. Take (k,l)∈X(k, l) \in X. By the invariant k≥ik \ge i and l≤jl \le j. Assume l=jl = j. Since column jj is sorted and k≥ik \ge i, M[k][j]≥M[i][j]>xM[k][j] \ge M[i][j] > x, which contradicts M[k][l]=xM[k][l] = x. So l≤j−1=j′l \le j - 1 = j'. The new bounds hold, since j≥0j \ge 0 gives j′≥−1j' \ge -1.
  • Case M[i][j]<xM[i][j] < x. Line L5 sets i′=i+1i' = i + 1. Take (k,l)∈X(k, l) \in X, with k≥ik \ge i and l≤jl \le j. Assume k=ik = i. Since row ii is sorted and l≤jl \le j, M[i][l]≤M[i][j]<xM[i][l] \le M[i][j] < x, a contradiction. So k≥i+1=i′k \ge i + 1 = i'. The new bounds hold, since i<mi < m gives i′≤mi' \le m.

So the invariant holds before the next test.

A returned pair is correct. Line L3 returns (i,j)(i, j) only when M[i][j]=xM[i][j] = x, so (i,j)∈X(i, j) \in X.

NIL is correct. Line L6 runs only when the test of line L2 fails, that is i≥mi \ge m or j<0j < 0. If (k,l)∈X(k, l) \in X, the invariant gives k≥i≥mk \ge i \ge m or l≤j<0l \le j < 0. Both contradict that (k,l)(k, l) is a cell, so XX is empty.

Termination and the bound. Let p=i−jp = i - j. At the start p=−(n−1)p = -(n - 1). Each pass that does not return raises ii by one or lowers jj by one, so it raises pp by exactly one. A pass runs only when i≤m−1i \le m - 1 and j≥0j \ge 0, so p≤m−1p \le m - 1 at the start of each pass. The values of pp at the starts of the passes are distinct integers in [−(n−1),m−1][-(n-1), m-1], and there are m+n−1m + n - 1 such integers. So the loop makes at most m+n−1m + n - 1 passes, and each pass reads one cell. When m=0m = 0 or n=0n = 0 the test of line L2 fails at once and no cell is read.

Which copy is returned. Assume XX is not empty and the walk returns (i,j)(i, j). By the invariant, every cell of XX has row ≥i\ge i, so ii is the smallest row that holds xx, and every cell of XX in row ii has column ≤j\le j, so jj is the largest column of xx in row ii. ■\blacksquare

Back to Staircase search