Skip to content
Part IA Lent Term

The k-bit Counter: A Worked Example

The kk-bit binary counter is the canonical example for demonstrating all three amortised analysis methods on the same data structure. The contrast between worst-case and amortised cost is stark: a single INCREMENT can flip kk bits, but over nn increments, the average is constant.

Structure and Operation

A kk-bit counter stores an integer in binary. Bits are indexed 00 (LSB) to k1k-1 (MSB). An INCREMENT operation walks from bit 0 upward, flipping 1’s to 0 until it finds a 0, which it flips to 1.

INCREMENT(A):
    i = 0
    while i < k and A[i] == 1:
        A[i] = 0       // flip 1 to 0
        i = i + 1
    if i < k:
        A[i] = 1       // flip 0 to 1

Worst-case: incrementing from 2k12^k - 1 (all 1’s: 011110111\ldots1) flips all kk bits, costing Θ(k)\Theta(k).

Aggregate Analysis

Bit ii (counting from LSB as bit 0) flips every 2i2^i increments. Over nn increments (with n2kn \le 2^k), the number of flips of bit ii is:

n2i\left\lfloor \frac{n}{2^i} \right\rfloor

Total flips:

T(n)=i=0k1n2i<i=0n2i=n2=2nT(n) = \sum_{i=0}^{k-1} \left\lfloor \frac{n}{2^i} \right\rfloor < \sum_{i=0}^{\infty} \frac{n}{2^i} = n \cdot 2 = 2n

Amortised per INCREMENT: T(n)/n<2=O(1)T(n)/n < 2 = O(1).

Concrete trace: n=16n = 16, k=4k = 4

BitFlip intervalFlips in 16 increments
0Every 116
1Every 28
2Every 44
3Every 82
Total30

30<216=3230 < 2 \cdot 16 = 32. Amortised: 30/16=1.87530/16 = 1.875.

Accounting Method

Amortised cost per INCREMENT: c^=2\hat{c} = 2.

Rules:

  • Flipping 0 to 1: actual cost 1, amortised 2 (stores 1 credit on this bit)
  • Flipping 1 to 0: actual cost 1, amortised 0 (consumes the credit stored on this bit)

Invariant: every 1-bit in the counter has 1 credit.

Verification for INCREMENT with tt trailing 1’s: tt flips of 1→0 consume tt credits (net 0 amortised each). One flip of 0→1 costs 1 and stores 1 credit (net 2 amortised). Total amortised: t0+2=2t \cdot 0 + 2 = 2. Credits never go negative because we only flip a 1 to 0 if it existed (and thus had a credit).

Step-by-step trace: 0 → 1 → 2 → 3 → 4

IncrementStateActual costBits flippedAmortisedCredits after
0→1000110→121 on bit 0
1→2001021→0, 0→121 on bit 1
2→3001110→121 on bits 0,1
3→4010031→0, 1→0, 0→121 on bit 2

Amortised consistently 2, actual varies 1-3.

Potential Method

Potential: Φ(D)=number of 1-bits in the counter\Phi(D) = \text{number of 1-bits in the counter}.

Clearly Φ(D0)=0\Phi(D_0) = 0 (counter starts at 0) and Φ(D)0\Phi(D) \ge 0.

For an INCREMENT converting tt trailing 1’s to 0 and one 0 to 1, the actual cost is c=t+1c = t + 1. The number of 1-bits changes from bb to bt+1b - t + 1, so:

ΔΦ=(bt+1)b=1t\Delta\Phi = (b - t + 1) - b = 1 - t

Amortised cost:

c^=c+ΔΦ=(t+1)+(1t)=2\hat{c} = c + \Delta\Phi = (t + 1) + (1 - t) = 2

Again, O(1)O(1) amortised.

Trace: 0111 → 1000 (increment from 7 to 8)

  • Before: state 0111, Φ=3\Phi = 3 (three 1’s)
  • Actual cost: flip bits 0,1,2 from 1→0 (cost 3), flip bit 3 from 0→1 (cost 1), total c=4c = 4
  • After: state 1000, Φ=1\Phi = 1 (one 1)
  • ΔΦ=13=2\Delta\Phi = 1 - 3 = -2
  • c^=4+(2)=2\hat{c} = 4 + (-2) = 2

The drop in potential (2-2) offsets the unusually high actual cost (44), keeping the amortised cost constant.

Contrast: Worst-Case Single Operation

Increment from 2k12^k - 1 (binary all 1’s) flips all kk bits. Actual cost: kk. But this happens only once per 2k2^k increments. The amortised analysis correctly averages this spike over the entire cycle.

Summary

MethodApproachResult
AggregateTotal flips <2n< 2n, divide by nn<2< 2 per increment
AccountingCharge 2, credit on 1-bits22 per increment
PotentialΦ=#\Phi = \# of 1’s, c^=c+ΔΦ\hat{c} = c + \Delta\Phi22 per increment
Worst-caseSingle increment at all 1’skk per increment

All three methods confirm O(1)O(1) amortised per INCREMENT, whilst the worst case is Θ(k)\Theta(k). This is the textbook demonstration that amortised analysis can reveal dramatically better average performance than worst-case analysis suggests.

Past Tripos: y2024p1q9, y2023p2q7.