Skip to content
Part IA Lent Term

Marking and Cascading Cuts

The Mark Bit

Each node in a Fibonacci heap carries a boolean marked flag. By definition:

A node is marked if it has lost exactly one child since it became a child of its current parent.

Nodes in the root list are never marked (they have no parent, so the concept is meaningless for them). When a node is first cut and moved to the root list, its marked flag is reset to false.

When Does Marking Occur?

When decrease-key causes a node x to violate the min-heap property (new key < parent’s key):

  1. x is cut from its parent and moved to the root list.
  2. If x’s parent p is not in the root list, we mark p.
  3. If p was already marked, we cut p as well — this is the cascading cut.

The rule: a node can lose at most one child and remain in place. Losing a second child forces the node itself to be cut.

Cascading Cut Algorithm

decrease-key(fh, ptr_k, nk):
    ptr_k.key = nk
    if ptr_k.parent != NIL and ptr_k.key < ptr_k.parent.key:
        do:
            if !ptr_k.parent.marked:
                CHOP-OUT(fh, ptr_k)
                break
            else:
                CHOP-OUT(fh, ptr_k)
                ptr_k = ptr_k.parent
        while ptr_k.parent != NIL
    if fh.min_ptr.key > nk:
        fh.min_ptr = ptr_k_orig

CHOP-OUT performs:

  • Update parent’s child pointer (if this was the only/designated child)
  • Decrement parent’s degree
  • If parent has a parent (i.e. is not a root), mark it
  • Remove the node from its sibling list
  • Set node’s parent = NIL, marked = false, left = right = itself
  • Splice into root list

The loop propagates upward: as long as the parent was already marked, it gets cut too, and we continue to its parent.

Why Cascading Cuts? The Grandchild Rule

The cascading cut rule guarantees a crucial structural invariant, sometimes called the grandchild rule:

Consider a node xx with degree dd. Order its children y1,y2,,ydy_1, y_2, \ldots, y_d by the time they became children of xx (earliest first). Then for all i{1,,d}i \in \{1, \ldots, d\}, the number of grandchildren of xx via child yiy_i satisfies: children(yi)i2\text{children}(y_i) \ge i - 2

Reasoning: When xx acquired child yiy_i, both xx and yiy_i had degree i1i-1 (since xx already had i1i-1 children). After the link, yiy_i could lose at most one child (the second loss would trigger a cascading cut, separating yiy_i from xx). So yiy_i‘s degree is at least (i1)1=i2(i-1) - 1 = i-2.

This gives the name “Fibonacci heap” because this recurrence leads to Fibonacci numbers.

The Fibonacci Number Connection

Let sds_d be the minimum number of nodes in a subtree whose root has degree dd. From the grandchild rule:

sd2+i=2dsi2s_d \ge 2 + \sum_{i=2}^{d} s_{i-2}

With base cases s0=1s_0 = 1, s1=2s_1 = 2. By induction, sdFd+2s_d \ge F_{d+2} where FkF_k is the kk-th Fibonacci number (F1=1,F2=1,F3=2,F_1 = 1, F_2 = 1, F_3 = 2, \ldots). Since Fd+2ϕdF_{d+2} \ge \phi^d with ϕ=(1+5)/21.618\phi = (1+\sqrt{5})/2 \approx 1.618, we get dlogϕn=O(logn)d \le \log_\phi n = O(\log n).

Worked Example: Cascading Cut Chain

Consider a min-heap tree: root RR (key 3, marked false) has children AA (key 5, marked false), BB (key 8, marked false). AA has child CC (key 10, marked false). CC has child DD (key 12).

       3(R)
      /    \
    5(A)   8(B)
    /
  10(C)
  /
12(D)

Step 1: Call decrease-key on D, setting key to 1. Since 1<101 < 10 (C’s key), cut D. D goes to root list. C becomes marked. C was unmarked, so stop.

Roots: [D:1]  +  3(R)-5(A)-10(C✓)-8(B)

Step 2: Call decrease-key on C, setting key to 2. Since 2<52 < 5 (A’s key), cut C. C goes to root list, unmarked. A was unmarked, becomes marked. Stop.

Roots: [D:1, C:2]  +  3(R)-5(A✓)-8(B)

Step 3: Call decrease-key on A, setting key to 0. Since 0<30 < 3 (R’s key), cut A. A goes to root list, unmarked. R is a root (parent NIL), so R is not marked. Stop.

Roots: [D:1, C:2, A:0]  +  3(R)-8(B)

Step 4: Alternative scenario where cascading triggers. Suppose after step 1, we call decrease-key on C (key 3) while A was already marked. Cut C. C goes to root list. A is already marked, so A is also cut! A goes to root list. Now check A’s parent R. R was not marked, so mark R and stop. Two nodes cut for the price of one decrease-key.

Summary

ConceptRule
Mark bitSet when a node loses its first child
Cascading cutTriggered when a marked node loses a second child
Root nodesNever marked
Cut nodeBecomes unmarked on entering root list
Grandchild ruleyiy_i’s degree i2\ge i-2 when ordered by attachment time
Structural guaranteesdFd+2s_d \ge F_{d+2}, implying d=O(logn)d = O(\log n)
Name originMinimum subtree sizes grow like Fibonacci numbers