Dynamic Arrays: Amortized Analysis
Dynamic arrays (Python lists, Java ArrayLists, C++ vectors) provide amortised append by doubling capacity when full. All three amortised analysis methods confirm this bound.
The Data Structure
A dynamic array stores elements in an underlying static array. When the array fills up (), a new array of double the capacity is allocated, all elements are copied, and the old array is freed.
- append: write element at position size, then size++. If size == capacity before the write, resize first.
- Actual cost: normally, when copying elements during resize.
Aggregate Analysis
Starting from capacity 1, resizes occur at sizes . Total element copies over appends:
Plus writes for the appends themselves. Total cost: . Amortised per append: .
Accounting Method
Charge per append:
- 1 unit pays for writing the element
- 2 units are stored as credit on the inserted element
When resizing from capacity to , the elements in the array have accumulated total credit. Copying them costs , consuming credits. The remaining credits are “lost” with the old array, but this is acceptable because elements in the new array will accumulate fresh credits.
Crucial insight: the credit on each element only needs to last until the next resize. At any point, at most half the elements (those in the first half of the array) need to have accumulated their 2 credits, because the resize only copies the first half’s worth of elements once. The inequality holds: total credit stored total copying cost over any sequence.
Potential Method
Define the potential function:
This is always non-negative (since , and — the array doubles only when full, so capacity is at most twice the size at all times except right after a resize).
(size = 0, capacity = 1: — this is not !). Fix: start with capacity 0, or define . With capacity 0 initially, .
Append without resize (size , capacity , ):
- Actual cost: (one write)
Append with resize (size , old capacity , new capacity ):
- Actual cost: (one write plus copies)
- Before: , After:
Amortised cost per append: consistently.
Deletion and Shrinking
To maintain amortised for both append and delete (pop), shrink the array when the load factor drops below . When deleting causes , halve the capacity. This prevents thrashing (alternating append/delete triggering resize every time).
Potential function for both operations: , or the textbook variant for append-heavy and a symmetric form for delete-heavy.
Summary
| Method | Result | Key detail |
|---|---|---|
| Aggregate | amortised | Sum of copies |
| Accounting | amortised | Charge 3, store 2 credits per element |
| Potential | amortised | |
| Shrink threshold | load factor | Prevents thrashing |
Past Tripos: y2024p1q9, y2023p2q7.