Algorithm Search⌘K

Proofs: Queue with minimum

These are the human proofs of Queue with minimum, at full length.

The two-stack queue with minimum is a FIFO queue and returns its least item full

This proof shows: correctness, amortized.

Setting. The structure has two stacks with minimum, InIn and OutOut. We use only their laws: PUSH adds an item at the top, POP removes and returns the top item, and MIN returns the least item of a non-empty stack. Write In=⟨a1,…,ap⟩In = \langle a_1, \ldots, a_p \rangle and Out=⟨b1,…,br⟩Out = \langle b_1, \ldots, b_r \rangle, each from the bottom to the top.

Invariant (Q). The queue, from the front to the back, is

⟨br,br−1,…,b1,a1,a2,…,ap⟩.\langle b_r, b_{r-1}, \ldots, b_1, a_1, a_2, \ldots, a_p \rangle.

So the front is the top of OutOut when OutOut is not empty, and the back is the top of InIn.

At the start both stacks are empty and the queue is empty, so (Q) holds.

ENQUEUE(Q,x)(Q, x). Line L1 pushes xx on InIn, so ap+1=xa_{p+1} = x. By (Q) the queue becomes ⟨br,…,b1,a1,…,ap,x⟩\langle b_r, \ldots, b_1, a_1, \ldots, a_p, x \rangle, which is the old queue with xx at the back.

DEQUEUE(Q)(Q), the queue not empty.

Case r≥1r \ge 1. Line L2 skips the transfer. Line L5 pops brb_r from OutOut and returns it. By (Q) brb_r is the front item, and the rest ⟨br−1,…,b1,a1,…,ap⟩\langle b_{r-1}, \ldots, b_1, a_1, \ldots, a_p \rangle is the old queue without its front.

Case r=0r = 0. Then p≥1p \ge 1, because the queue is not empty. The loop of lines L3 and L4 keeps this loop invariant at its test: for some 0≤t≤p0 \le t \le p, In=⟨a1,…,ap−t⟩In = \langle a_1, \ldots, a_{p-t} \rangle and Out=⟨ap,ap−1,…,ap−t+1⟩Out = \langle a_p, a_{p-1}, \ldots, a_{p-t+1} \rangle from the bottom to the top. It holds for t=0t = 0. One iteration pops ap−ta_{p-t} from InIn and pushes it on OutOut, which gives the invariant for t+1t + 1. The value tt grows by exactly 1 in each iteration, and the loop stops when InIn is empty, at t=pt = p. Then Out=⟨ap,…,a1⟩Out = \langle a_p, \ldots, a_1 \rangle with a1a_1 at the top, and InIn is empty. In the notation of (Q), r=pr = p and bj=ap+1−jb_j = a_{p+1-j}, so the queue read by (Q) is ⟨a1,…,ap⟩\langle a_1, \ldots, a_p \rangle, which is unchanged. Line L5 then pops a1a_1, the front item, as in the first case.

MIN(Q)(Q), the queue not empty. The set of items of the queue is the union of the items of InIn and of OutOut, by (Q). If InIn is empty, line L6 returns the least item of OutOut, which is the least item of the queue. If OutOut is empty, line L7 returns the least item of InIn. Otherwise line L8 returns the smaller of the two minima, which is the least item of the union. Nothing changes.

Amortized cost. Count one unit for each PUSH and each POP on InIn or OutOut; each costs O(1)O(1) on a stack with minimum. Let Φ=2p\Phi = 2p, twice the size of InIn. Then Φ≥0\Phi \ge 0 and Φ=0\Phi = 0 at the start.

  • ENQUEUE costs 1 and raises Φ\Phi by 2: amortized cost 3.
  • DEQUEUE without a transfer costs 1 and does not change Φ\Phi: amortized cost 1.
  • DEQUEUE with a transfer of pp items costs 2p+12p + 1, and Φ\Phi drops from 2p2p to 0: amortized cost 1.
  • MIN costs at most two MIN calls on stacks, and does not change Φ\Phi: amortized cost O(1)O(1).

The sum of the potential differences telescopes, so for any sequence of mm operations from the start, the total cost is at most the sum of the amortized costs minus the final potential, which is at most 3m3m stack operations. ■\blacksquare

Back to Queue with minimum