Amortized Analysis

Learn to analyze sequences of operations using potential functions, proving that expensive operations are rare enough to be efficient

When Worst-Case Isn't the Whole Story

Sometimes individual operations can be expensive, but they "pay for themselves" by making future operations cheaper. Amortized analysis captures this by spreading costs over sequences of operations.

The potential method assigns "potential energy" to data structure states. Expensive operations drain potential that cheap operations accumulated. If potential never goes negative, total actual cost ≤ total amortized cost.

In this section, you'll see how dynamic arrays achieve O(1) amortized insertion, how splay trees achieve O(log n) amortized access, and how to design your own potential functions.

Demo 1: Dynamic Arrays

Inserting into a full array requires copying all n elements — an O(n) operation. But with the potential function Φ = 2n - capacity, each insert has amortized cost O(1). Watch the potential rise and fall!

32

Potential Function: Φ = 2n - capacity

When we insert without resizing, potential increases by 2 (amortized cost = 1 + 2 = 3). When we resize (double), potential drops by n (amortized cost = n + 1 - n = 1).

Cost per Operation

Insert 1 Normal ResizeInsert 32

Cumulative Cost

n insertions Actual Amortized
Total Actual
63
Total Amortized
95
Avg Actual
1.97
Resizes
5
log₂(32)
Show Operation Details
OpActualΦ beforeΦ afterΔΦAmortized
+ 1101+12
🔄 2212+13
🔄 3322+03
+ 4124+23
🔄 5542-23
+ 6124+23
+ 7146+23
+ 8168+23
🔄 9982-63
+ 10124+23
+ 11146+23
+ 12168+23
+ 131810+23
+ 1411012+23
+ 1511214+23
+ 1611416+23
🔄 1717162-143
+ 18124+23
+ 19146+23
+ 20168+23
+ 211810+23
+ 2211012+23
+ 2311214+23
+ 2411416+23
+ 2511618+23
+ 2611820+23
+ 2712022+23
+ 2812224+23
+ 2912426+23
+ 3012628+23
+ 3112830+23
+ 3213032+23

Key Insight:

Even though individual insertions can cost O(n), the average cost over n insertions is only O(1) because expensive resizes are rare and "paid for" by the potential accumulated during cheap insertions.

Demo 2: Binary Counter

Incrementing a binary counter can flip many bits (like 0111 → 1000 flips 4 bits). But with Φ = number of 1-bits, the amortized cost per increment is just O(1). Each 1→0 flip uses potential saved by a previous 0→1 flip.

Potential Function: Φ = number of 1-bits

Incrementing a binary counter flips trailing 1s to 0s, then one 0 to 1. Each 0→1 flip costs 1 and increases Φ by 1 (amortized = 2). Each 1→0 flip costs 1 but decreases Φ by 1 (amortized = 0).

16
Counter Value: 0Potential Φ = 0
2-6
0
2-5
0
2-4
0
2-3
0
2-2
0
2-1
0

Bit Flips per Increment

Notice spikes at powers of 2 (many trailing 1s to flip)
Total Flips
0
Avg Flips
0.00
Amortized Total
0
Amortized Avg
0.00

Why O(1) Amortized?

Each increment flips one bit from 0→1 (adds 1 to Φ) and possibly many bits from 1→0 (subtracts from Φ). But we can only flip 1→0 if we previously flipped 0→1. Over n increments: total flips ≤ 2n.

Demo 3: Splay Tree Amortization

Splay trees move accessed nodes to the root, potentially requiring O(n) rotations. The rank-based potential function Φ = Σ log₂(size(x)) proves that each access costs O(log n) amortized.

Potential Function: Φ = Σ rank(x) = Σ ⌊log₂(size(x))⌋

Each node's rank depends on its subtree size. Splaying moves accessed nodes to the root, restructuring the tree. Heavy nodes near leaves contribute more to potential than when at the root.

1s=72s=63s=54s=45s=36s=27s=1
Click a node to splay it to the root:
Potential Φ
10
Tree Depth
7
Accesses
0
Show Amortized Analysis
Total Actual Cost
28
Total Amortized Cost
25.0
AccessRotationsΦ beforeΦ afterAmortized
4310.05.0-1.0
215.06.03.0
636.05.03.0
135.06.05.0
736.07.05.0
347.07.05.0
547.07.05.0

Why O(log n) Amortized?

The Access Lemma proves that splaying has amortized cost ≤ 3(rank(root) - rank(x)) + 1. Since rank(root) = O(log n) and rank(x) ≥ 0, each access costs O(log n) amortized.

Demo 4: The Potential & Accounting Methods

Explore different amortized analysis techniques: the potential method uses energy functions, while the accounting method assigns credits to operations. Both prove the same O(1) amortized bounds!

Potential Function: Φ = stack size

PUSH costs 1 and increases Φ by 1 → amortized cost = 2. MULTIPOP(k) costs k but decreases Φ by k → amortized cost = 0.

PUSHPUSHPUSHPUSHPUSHPOP(3)PUSHPUSHPOP(10)
OperationActualΦ beforeΦ afterΔΦAmortized
push101+12
push112+12
push123+12
push134+12
push145+12
multipop(3)352-30
push123+12
push134+12
multipop(4)440-40
Total Actual
14
Total Amortized
14
Per-Op Amortized
O(1)
Common Potential Functions
Dynamic Array
Φ = 2n - capacity
Ensures amortized O(1) insertion with doubling
Stack with Multipop
Φ = n (number of elements)
Each push adds 1 potential, multipop uses it
Binary Counter
Φ = number of 1-bits
Incrementing flips 1s to 0s, paying back potential
Splay Tree
Φ = Σ rank(x) = Σ ⌊log₂(size(x))⌋
Rank-based potential for O(log n) amortized access
Fibonacci Heap
Φ = trees + 2·marks
Accounts for cascading cuts in decrease-key

Amortized Analysis Mastered!

You now understand how to prove amortized bounds:

  • Potential method: Φ maps states to non-negative reals
  • Amortized cost = actual cost + ΔΦ
  • Dynamic arrays: Φ = 2n - capacity → O(1) insert
  • Binary counter: Φ = #ones → O(1) increment
  • Splay trees: Φ = Σ rank → O(log n) access

Next: We'll explore Union-Find with path compression and the mysterious inverse Ackermann function — achieving nearly O(1) per operation!