For the complete documentation index, see llms.txt. This page is also available as Markdown.

16. Amortized Analysis

Exercises

16.1-1

Available in the latest revision of the IM.

16.1-2

Available in the latest revision of the IM.

16.1-3

Available in the latest revision of the IM.

16.2-1

Available in the latest revision of the IM.

16.2-2

Available in the latest revision of the IM.

16.2-3

Available in the latest revision of the IM.

16.3-1

Available in the latest revision of the IM.

16.3-2 🌟

Available in the latest revision of the IM.

Reverse-engineering the potential function

Let’s derive the formula Φ(Di)=2i2lgi+1\Phi(D_i) = 2i - 2^{\lfloor \lg i \rfloor + 1} for i>0i > 0 from the IM.

1

Identify the debt

At step i=2ki = 2^k, we are going to get hit with a massive bill of 2k2^k. We need to pay for this using the potential we saved up during the cheap operations.

2

Calculate the savings rate

The previous expensive operation happened at i=2k1i = 2^{k-1}. The current one is at i=2ki = 2^k. The number of cheap steps between them is 2k12^{k-1}. During this period, we must accumulate enough potential to pay for the next expensive operation. Therefore, we must increase it by 2 at every single cheap step.

3

Translate to formula

Φ(Di)=2×(items added since the last exact power of 2)=2(i2lgi)=2i2lgi+1.\Phi(D_i) = 2 \times (\text{items added since the last exact power of 2})=2(i - 2^{\lfloor \lg i \rfloor})= 2i - 2^{\lfloor \lg i \rfloor + 1}.

16.3-3 🌟

Available in the latest revision of the IM.

16.3-4

Available in the latest revision of the IM.

16.3-5

Available in the latest revision of the IM.

16.3-6

Available in the latest revision of the IM.

16.4-1

Available in the latest revision of the IM.

16.4-2 🌟

Available in the latest revision of the IM.

16.4-3

Available in the latest revision of the IM.

16.4-4

Available in the latest revision of the IM.

Problems

16-1 Binary reflected Gray code

Available in the latest revision of the IM.

16-2 Making binary search dynamic

Available in the latest revision of the IM.

16-3 Amortized weight-balanced trees

a.

The initial call is Rebuild-Subtree(T, x).

b.

Search takes O(h)O(h) worst-case time, where hh is the height of a BST. After hh steps down the tree, the number of nodes remaining in a subtree is at most nαhn \alpha^h. Since the smallest possible subtree has 1 node (a leaf), we have:

nαh1    hlog1/αn=O(lgn).n \alpha^h \ge 1 \implies h \le \log_{1/\alpha} n = O(\lg n).

Therefore, performing a search in an nn-node α-balanced binary search tree takes O(lgn)O(\lg n) worst-case time.

c.

By definition, Δ(x)0\Delta(x) \ge 0 for all xx, thus any BST has nonnegative potential (assuming that the constant multiplier cc is positive). A 1/2-balanced tree is, in a sense, as balanced as it can be. Therefore, it has Δ(x)1\Delta(x) \le 1 for all xx. This entails that a 1/2-balanced tree has potential 0.

d.

To determine how large the constant cc must be, we need to ensure that the drop in the potential function Φ\Phi during a rebuild is large enough to completely pay for the mm units of actual work required to rebuild the mm-node subtree.

A rebuild is triggered exactly when a node xx (where x.size=mx.size = m) ceases to be α\alpha-balanced. This happens when an insertion (or symmetrically deletion) pushes the size of its heavier child strictly above the threshold αm\alpha m. Let the heavier child's size be hh. We know h>αmh > \alpha m. Let the lighter child's size be ll. Because the total size is mm and the root xx itself counts as 1 node, l=m1hl = m - 1 - h. Now, let's calculate the size difference Δ(x)\Delta(x) for this node at the exact moment the threshold is crossed:

Δ(x)=hl=2hm+1    Δ(x)>m(2α1)+1.m(2α1).\Delta(x) = h - l= 2h - m + 1 \implies \Delta(x) > m(2\alpha - 1) + 1. \approx m(2\alpha - 1).

Before the rebuild, the potential at node xx alone is cΔ(x)c \cdot \Delta(x). After the rebuild, the entire subtree is 1/2-balanced. As we proved previously, a 1/2-balanced tree has a potential of exactly 0. Furthermore, rebuilding the subtree rooted at xx does not change the sizes of any ancestors of xx, so their potentials remain untouched. Therefore, the total drop in potential in the system is at least the potential that was stored at xx. We need to ensure

c^i=ci+Δ(Φi)=mcm(2α1)0    c12α1.\hat c_i =c_i+\Delta(\Phi_i) =m-cm(2\alpha-1) \le 0 \implies c \ge \frac{1}{2\alpha - 1}.

Because α>1/2\alpha > 1/2, the denominator (2α1)(2\alpha - 1) is always a strictly positive fraction. If α\alpha is close to 1/2 (meaning the tree is kept very strictly balanced), then it forces cc to be very large—we have to aggressively save a lot of potential during regular operations to pay for the frequent, inevitable rebuilds!

e.

Inserting a node into or deleting a node from an n-node α-balanced tree costs O(lgn)O(\lg n) time in the worst-case. If such an operation triggers a rebalancing action, then by part (d), we know that rebuilding a subtree to make it 1/2-balanced takes O(1)O(1) amortized time.

Because the tree is α\alpha-balanced before the operation, its height is strictly O(lgn)O(\lg n). Therefore, there are at most O(lgn)O(\lg n) ancestors on the search path for a new slot or toward the node to be deleted. For any ancestor on this path, the size of exactly one of its subtrees (either left or right) changes by exactly 1. The other subtree remains unchanged. Since the potential function is Φ(T)=cΔ(x)\Phi(T) = c \sum \Delta(x), each node on the path contributes at most c1c \cdot 1 to the new potential. With O(lgn)O(\lg n) nodes involved, the total maximum increase in the tree's potential is cO(lgn)=O(lgn)c \cdot O(\lg n) = O(\lg n).

Therefore, inserting a node into or deleting a node from an nn-node α-balanced tree costs O(lgn)O(\lg n) amortized time.

16-4 The cost of restructuring red-black trees

Available in the latest revision of the IM.

Last updated