See Chapter 5.1 of the Okasaki textbook for a summary of two approaches to amortized analysis, the banker’s method and the physicist’s method. Here, we will say just a few extra words about the accounting for the `FastQueue`

implementation from before.

Recall that when evaluating the running times of functions, we often use symbolic constants instead of concrete units (such as seconds) in order to abstract away from low-level, incidental, and variable characteristics of an execution environment. And because Big-O analysis, furthermore, abstracts away the particular constants of a function, symbolic constants (such as *k*) are often replaced by particular small constants (such as *1*).

Once comfortable with such reasoning, we can often jump directly to saying things like “the amortized cost of `enqueue`

is *2*” and “the amortized cost of `dequeue`

is *1*”. In the meantime, let us spend the extra effort to explicitly account for the actual (symbolic) costs of operations before reducing them to their asymptotic characteristics.

To avoid confusion with the notation *c* for credits from the textbook, here we will use the metavariable *k* to range over constants. Let the following constants stand for actual costs of the various operations on a `Queue`

that contains *m* elements in the `back`

list:

*k*is the cost of_{1}`enqueue`

;*k*is the cost of_{2}`peek`

;*k*is the cost of_{3}`dequeue`

when`List.reverse`

is not called (the cheap case); and*k*is the cost of_{4}m + k_{5}`dequeue`

when`List.reverse`

is called (the expensive case).

Notice the actual cost of `dequeue`

in the expensive case is linear in the size of the `back`

list.

We now revisit the amortized analyses from the textbook using the symbolic costs above.

We allocate *k _{4}* credits for each element added to the

`back`

, where `List.reverse`

to process one element.`enqueue`

:*k*_{1}+ k_{4}- 0 = k_{1}+ k_{4}`peek`

:*k*_{2}+ 0 - 0 = k_{2}`dequeue`

(cheap):*k*_{3}+ 0 - 0 = k_{3}`dequeue`

(expensive):*(k*_{4}m + k_{5}) + 0 - k_{4}m = k_{5}

Thus, all of the operations run in *O(1)* amortized time.

We define the potential to be *k _{4}m* where

`back`

.`enqueue`

:*k*_{1}+ k_{4}(m+1) - k_{4}m = k_{1}+ k_{4}`peek`

:*k*_{2}+ k_{4}m - k_{4}m = k_{2}`dequeue`

(cheap):*k*_{3}+ k_{4}m - k_{4}m = k_{3}`dequeue`

(expensive):*(k*_{4}m + k_{5}) + k_{4}0 - k_{4}m = k_{5}

Thus, all of the operations run in *O(1)* amortized time.

- Okasaki, Chapter 5.1 and 5.6

- Okasaki, Chapter 5.3 (
`BinomialHeap.insert`

runs in*O(1)*amortized time.)