CSE3144 Β· Advanced Data Structures Β· Jul–Nov Semester 2026 Β· Lecture 19 of 36 Β· CO CSE3144.3

Fibonacci Heaps & Amortized Efficiency

Binomial heaps fixed merging but left DECREASE-KEY at O(log n). Today's structure gets it down to O(1) amortized β€” by doing almost nothing when you'd expect it to do work, and paying the bill later, all at once, whenever EXTRACT-MIN forces a cleanup.

Dr. Manu ShrivastavaCourse Instructor Β· Consultation Fri 2–5 PM, LHC 308F
~95 minutesSession outcome: analyze lazy operations and amortized complexity
L19 Β· 00 β€” Agenda ~128 min

Today, minute by minute

Why Fibonacci heaps β€” the decrease-key gap

00–06

Dijkstra and Prim call decrease-key far more often than extract-min. O(log n) per call adds up fast.

Where DECREASE-KEY earns its keep

06–11

One minute of Dijkstra: extract-min once per vertex, decrease-key once per edge.

Structure: the one rule β€” ordered by key

11–15

Circular doubly-linked lists, degree, mark β€” and the "do nothing now, clean up later" philosophy.

Structure: no shape rules at all

15–19

Same 8 nodes as a binomial B3, none of the rules β€” and why giving up order is the whole point.

Structure: how it is stored

19–23

Four pointers per node, circular doubly-linked lists, and the single pointer that is the heap.

Structure: the mark bit

23–28

Lose one child quietly, lose two and you are cut loose β€” the cascading cut, animated.

Structure: what the mark bit prevents

28–32

Degree must be earned: a second loss disconnects the child and drops the parent's degree with it.

Animation: INSERT

32–37

Add a singleton tree to the root list. That's the whole operation.

Animation: EXTRACT-MIN, in full

37–61

Remove the root, promote its children, then consolidate β€” every array check, every link.

Animation: MERGE / UNION

61–65

Splice two circular root lists together. O(1), regardless of size.

Animation: DECREASE-KEY, all three cases

65–79

No cut, a single cut, and a cascading cut β€” traced on the same heap.

Animation: DELETE

79–91

Decrease to −∞, then extract-min β€” no new machinery needed.

The potential function Φ = t(H) + 2m(H)

91–95

Trees measure looseness; marks measure deferred cleanup debt.

Why the coefficient on marks is 2

95–99

One cascading cut through the formula, both ways — and why INSERT is charged a surcharge rather than a refund.

Why decrease-key is O(1): the common case

99–102

One cut, one mark, no cascade — and the +3 it banks for later.

Why decrease-key is O(1): with a cascade

102–108

Actual cost O(c), potential falls by c — the two cancel whatever the length.

Why extract-min is amortized O(log n)

108–112

The potential drop pays for almost all of the consolidation work.

Advantages & limitations

112–117

The best known amortized bounds β€” at the cost of real-world constants and real implementation complexity.

Complexity, all three heap families

117–120

Binary vs. binomial vs. Fibonacci, side by side.

Where this actually runs

120–124

Dijkstra's algorithm, Prim's MST, and why theory doesn't always win in practice.

Recap & what's next

124–128

Lecture 20: Pairing Heaps and Double-Ended Priority Queues.

CSE3144 β€” Lecture 19
L19 Β· 01 β€” Why Fibonacci heaps? ~6 min

The operation that gets called the most is the one still costing O(log n)

Real-life example β€” road-network routing

Think of Dijkstra's shortest-path algorithm computing fastest routes across a road network with millions of intersections. Every time it finds a shorter path to an intersection it has already seen, it must decrease that intersection's priority in the queue. This happens once per road segment examined β€” potentially millions of times β€” while EXTRACT-MIN (pulling out "visit this intersection next") happens only once per intersection.

Why binomial heaps still aren't enough

Lecture 18's binomial heap fixed merging, but DECREASE-KEY still costs O(log n) there β€” every decrease may need to bubble a node up through a binomial tree's structure. When decrease-key is called far more often than extract-min (exactly Dijkstra's and Prim's access pattern), that O(log n) constant is paid millions of times over.

The Fibonacci heap's answer

Make DECREASE-KEY amortized O(1) β€” by refusing to maintain a tidy tree shape at all times. A Fibonacci heap lets its structure get "messy" (many small trees, some nodes cut loose) during INSERT, UNION, and DECREASE-KEY, and only pays the cost of tidying up β€” consolidating everything into a clean shape β€” during EXTRACT-MIN. This is the "lazy" philosophy the whole structure is built around.

CSE3144 β€” Lecture 19 Β· Why Fibonacci heaps
L19 Β· 01a β€” Where DECREASE-KEY earns its keep ~5 min

One minute of Dijkstra, to see why that one operation matters

The previous slide claimed DECREASE-KEY is called far more often than EXTRACT-MIN. Rather than assert it, here is a five-vertex shortest-path run reduced to only its two heap operations — no predecessor arrays, no path reconstruction. Watch which one fires more, and watch the moment a vertex already sitting in the queue gets a better distance.

Interactive — Dijkstra from A, showing only the queue operations
Count them: the two operations are not called equally often
  • EXTRACT-MIN runs once per vertex. Each vertex is settled exactly once and never returns to the queue — |V| calls in total.
  • DECREASE-KEY runs once per edge. Every edge is examined once, from the settled end, and improves the far end's key whenever it offers a shorter route — up to |E| calls.
  • In this tiny run: 5 extract-mins against 6 decrease-keys. On a road network or a router topology, where each node has many neighbours, E vastly outweighs V.
So which operation should you optimise?

Total cost is |V| × (cost of EXTRACT-MIN) + |E| × (cost of DECREASE-KEY). With a binary heap both are logarithmic, so the E term dominates and drags the whole algorithm with it:

priority queueEXTRACT-MINDECREASE-KEYDijkstra total
binary heapO(log V)O(log V)O(E log V)
Fibonacci heapO(log V)O(1) amortizedO(E + V log V)

Making the rare operation faster would barely help. Making the common one free is what changes the bound — and that is the single problem the rest of this lecture solves.

CSE3144 β€” Lecture 19 Β· Why DECREASE-KEY matters
L19 Β· 02 β€” Structure: the one rule ~4 min

Ordered by key β€” and that is the only promise

A Fibonacci heap is a forest of min-heap-ordered trees. Every node's key is ≥ its parent's, exactly as in a binary heap. Hold on to that, because it is the only structural rule this heap enforces — the next slide is about everything it deliberately does not promise.

A perfectly legal Fibonacci heap
What min-heap order does buy you
  • Inside any one tree, the smallest key sits at that tree's root β€” keys only grow as you walk down.
  • So the global minimum must be one of the roots. A single pointer, min[H], is kept aimed at it, which makes MINIMUM Θ(1) β€” better than a binomial heap, which had to scan.
What it does not buy you
  • Nothing about siblings. Look at 18, 52 and 38 above β€” three children of the same node, in no relation to each other whatsoever.
  • Nothing about shape, degree, or tree count. The heap above has trees of degree 3, 1, 2 and 0 β€” in that order, with no pattern.
CSE3144 β€” Lecture 19 Β· Structure
L19 Β· 02a β€” Structure: no shape rules ~4 min

Where a binomial heap was rigid, this one promises nothing

Both trees below hold 8 nodes and both are perfectly legal — for their own structure. The difference is how much each one had to pay to stay in that shape.

Same 8 nodes, two different sets of rules
Three things a Fibonacci heap gives up
  • Children are in no sequence. "Unordered" here is the graph-theory sense β€” a node's children sit in their list in whatever order they happened to arrive.
  • Shape is unconstrained. No fixed child count, no Bk template. Any tree shape at all can occur.
  • The root list is unordered too, and duplicate degrees are allowed to pile up. A binomial heap could never hold two trees of the same degree; here they simply wait until EXTRACT-MIN consolidates them.
Why giving up order is the whole point

In Lecture 18 the child list was ordered by decreasing degree, and EXTRACT-MIN depended on it: it reversed that list to obtain a legal root list. Every operation had to preserve the invariant, and that upkeep is exactly what cost O(log n).

A Fibonacci heap has no invariant to preserve, so there is nothing to repair. EXTRACT-MIN just splices the children straight into the root list β€” no reversal, no ordering, no checks. DECREASE-KEY can rip a node out of the middle of a tree and drop it in the root list, and the structure is still legal by definition. Work you never promised to do is work you never have to pay for.

CSE3144 β€” Lecture 19 Β· No shape rules
L19 Β· 02b β€” Structure: how it is stored ~4 min

Four pointers per node β€” one more than a binomial heap, and it buys everything

Cutting a node out of the middle of a list in O(1) requires reaching its neighbours on both sides. That is the entire reason for the extra pointer.

What one node holds
keythe priority value
parent→ up to its parent (NIL for a root)
childany one child β€” just an entry point
left→ previous sibling
right→ next sibling
degreehow many children it has
markhas it lost a child? (next slide)

Note child points at an arbitrary child, not a leftmost one β€” with no ordering, "leftmost" would mean nothing.

Siblings form a circular, doubly-linked list

The three children of node 3, as they actually sit in memory:

18 52 38

Circular, so 38.right = 18 and 18.left = 38 β€” there is no first or last.

  • Remove any node in O(1) β€” x.left.right = x.right and x.right.left = x.left. No traversal, no head-of-list special case. This is what DECREASE-KEY's cut needs.
  • Splice two lists in O(1) β€” join them at any two points. This is what UNION and EXTRACT-MIN need.
  • Lecture 18 could do neither. Its singly-linked sibling chain could only be walked forwards, which is why removing anything meant finding its predecessor first.
The root list β€” and the one pointer that is the heap
3 17 24 7

The roots use the very same left/right fields to form one circular list, and min[H] points at the root holding the smallest key (3, highlighted). A whole Fibonacci heap is that single pointer. Adding a tree is an O(1) splice anywhere in the ring β€” which is why INSERT and UNION are O(1), and why the root list is in no particular order.

CSE3144 β€” Lecture 19 Β· Representation
L19 Β· 02c β€” Structure: the mark bit ~5 min

One bit per node, to stop trees being shredded

DECREASE-KEY works by cutting a node out and dropping it in the root list. Losing nodes is harmless in itself β€” the heap just gets flatter, and EXTRACT-MIN rebuilds the depth later. The danger is subtler: unchecked cuts would let a node keep a high degree while the subtrees beneath its children are gutted, and the whole analysis rests on high degree implying many descendants. The mark bit is the entire defence: a node may lose one child quietly, but not two. Below we start from a completely fresh tree with nothing marked, run four DECREASE-KEY calls, and watch the marks be earned one at a time — until the fourth call sets off a cut that propagates through three marked ancestors before a root finally stops it.

Interactive β€” the mark bit and the cascading cut
The rule, in three lines
  • mark[x] = "has x lost a child since the last time x itself became someone's child?" A freshly linked node starts unmarked.
  • Loses its first child → just set the mark. Nothing else happens.
  • Loses a second child while marked → x is cut loose too, and the same test is applied to its parent β€” the cascading cut.

Roots are never marked. A node moving to the root list has its mark cleared, and the cascade stops there β€” a root has no parent to punish.

The lazy philosophy, in one line

INSERT, UNION and DECREASE-KEY all do the minimum possible work and dump the mess into the root list. Only EXTRACT-MIN ever tidies up β€” a step called consolidation β€” and it amortizes that cleanup across all the cheap operations that ran before it.

You will watch cascading cuts run inside a full DECREASE-KEY in L19·06, and the amortized argument is made properly in L19·09.

CSE3144 β€” Lecture 19 Β· The mark bit
L19 Β· 02d β€” Structure: what the mark bit prevents ~4 min

A node must never keep a degree it has not earned

You have just watched a cut cascade four levels and flatten a tree. The fair question is: what was all that for? Here is the single thing the rule protects — and it is not the shape of the tree.

The thing the rule forbids: a hollow node

Both roots below report degree 4. Remember that degree counts direct children only — so cutting a node's grandchildren shrinks its subtree without touching its degree at all. That is the loophole.

The left one earned its degree: it was built by four links, and every child still carries the subtree it brought. The right one is a fraud — same degree, three fewer nodes, and it would be free to keep shrinking. If nodes like that were allowed, "degree 4" would tell you nothing about how many nodes lie beneath.

Interactive — why a second loss cannot be hidden
Why this is worth one bit on every node

Look again at the two trees above. The heap has no way to inspect a subtree β€” when it needs to organise its trees, the only thing it reads off a root is its degree. Every EXTRACT-MIN sorts the trees into slots, one slot per degree, and how long that takes depends on how many different degrees can turn up.

That is what makes a hollow node dangerous. If a node were allowed to keep a large degree while holding almost nothing beneath it, large degrees would become cheap β€” even a small heap could throw up a great many different ones, the slots would multiply, and every EXTRACT-MIN would have more of them to sweep.

The mark bit shuts that down. Because a second loss disconnects the child and costs the parent its degree, a node can only hold a big degree if it genuinely holds a big subtree. Big degrees stay expensive to obtain, so only a handful of different degrees can exist in a heap at any moment β€” and EXTRACT-MIN stays quick.

You will see those slots for yourself in L19·04, when EXTRACT-MIN consolidates: one slot per degree, filled and collided until at most one tree of each degree is left standing.

CSE3144 β€” Lecture 19 Β· What the mark bit prevents
L19 Β· 03 β€” Animation: INSERT ~5 min

Add one singleton tree to the root list β€” nothing else happens

Building a Fibonacci heap from scratch with four inserts. No comparison against any tree's internal structure is ever needed β€” only against the current min.

Interactive β€” INSERT 23, 7, 17, 24 into an empty heap
CSE3144 β€” Lecture 19 Β· INSERT
L19 Β· 04 β€” Animation: EXTRACT-MIN, in full ~24 min

Remove the root, promote its children, then consolidate β€” every single check

A 9-node heap: root list = {3(min, children 18 & 9), 20, 15(child 25), 8(child 40), 12}. Watch every array slot get checked, every collision, every link β€” nothing is skipped.

First β€” where did this heap come from? (it could not have come from inserts)

The last slide left every inserted node sitting as its own degree-0 root, so the obvious objection to the heap above is: how does anything have children yet? The answer is the point of this whole slide. Degree increases in exactly one place β€” consolidation, inside EXTRACT-MIN. INSERT never links; UNION only concatenates root lists; DECREASE-KEY only ever removes children. So a heap holding a degree-2 root has already survived at least one extract-min.

Here is the smallest case that builds one, step by step. Insert 3, 18, 9, 20, 15 β€” five flat roots β€” then run a single EXTRACT-MIN and watch the degree array do the work:

Interactive — five inserts, then one EXTRACT-MIN

One more clue in the heap below. Its roots are degree 2, 0, 1, 1, 0 — two of degree 1 and two of degree 0. Consolidation always leaves every degree distinct, so this heap is not sitting straight after one: an earlier extract-min built the degree-1 and degree-2 trees, and then further inserts piled fresh singletons on top. That is the normal life of a Fibonacci heap — inserts flatten it, extract-min tidies it, inserts flatten it again.

Interactive β€” EXTRACT-MIN(H)
CSE3144 β€” Lecture 19 Β· EXTRACT-MIN
L19 Β· 05 β€” Animation: MERGE / UNION ~4 min

Splice two circular lists together β€” O(1), regardless of size

H1 = {7(min), 23, 17, 24} — the heap built by the four inserts in L19·03. H2 = a fresh heap built from inserting 18, 52, 41 (min = 18).

Interactive β€” UNION(H1, H2)
CSE3144 β€” Lecture 19 Β· MERGE / UNION
L19 Β· 06 β€” Animation: DECREASE-KEY, all three cases ~14 min

No cut, a single cut, and a cascading cut β€” on the same tree

Continuing from EXTRACT-MIN's result: one tree, root 8, children 40, 15(child 25), 9(children 18, 12(child 20)). Every node starts unmarked β€” consolidation always unmarks a node when linking it.

Interactive β€” decrease 40→35, then 18→6, then 12→2
CSE3144 β€” Lecture 19 Β· DECREASE-KEY
L19 Β· 07 β€” Animation: DELETE ~12 min

Decrease to −∞, then extract-min β€” no new machinery required

Continuing from DECREASE-KEY's result: root list = {8(children 35, 15→25), 6, 2(child 20), 9}, min = 2. We'll delete node 15.

Interactive β€” DELETE(15)
CSE3144 β€” Lecture 19 Β· DELETE
L19 Β· 08 β€” The potential function ~4 min

Φ(H) = t(H) + 2·m(H) β€” trees measure looseness, marks measure debt

The two ingredients
  • t(H) = the number of trees currently in the root list. More trees means more looseness — more consolidation work waiting to happen.
  • m(H) = the number of currently marked nodes. Each mark is a standing debt: "one cascading cut is already pre-authorised here."

Both are plain counts of things you can see in the heap — nothing hidden, nothing derived. The next slide explains the one part of this formula that always draws a question: why marks are multiplied by 2.

Φ(H0) = 0 for an empty heap, and Φ(H) ≥ 0 always β€” both t(H) and m(H) are counts, never negative.
CSE3144 β€” Lecture 19 Β· Potential function
L19 Β· 08a β€” Why the coefficient on marks is 2 ~4 min

A mark is a promise of exactly two units of future work

The 2 is not a safety margin, and it is not chosen to make the algebra tidy. It is the size of the debt a mark represents — and you can itemise that debt the moment the mark is set, long before anything is cut.

Start from the mark, not from the cut

Setting a mark on a node y is a declaration: "y has already lost one child. If it loses another, y itself will be cut out of its parent." That future cut is now guaranteed to cost two separate things, and both can be priced immediately:

the promised cut will needbecause
1 unit — to perform the cutsplicing y out and moving it to the root list is O(1) work, and somebody has to pay for it
1 unit — to endow the new treey becomes a root, so t rises by 1 — and every tree must carry one unit for the consolidation EXTRACT-MIN will eventually do on it

Total liability: 2 units, incurred the instant the mark is set. So a mark must be worth 2 in Φ. Not 2 because the arithmetic works out — 2 because that is what it owes. The operation that sets the mark pays the deposit up front (that is the +2 inside the +3 you saw on L19·09), and it sits at exactly the node where the work will later be needed.

Check it: run one real cut through the formula

When the promise is called in, the cut node joins the root list (one more tree) and its mark is cleared (one fewer mark). Apply Φ to the state before and to the state after:

Φbefore = t + 2m
Φafter  = (t + 1) + 2(m − 1)

and subtract:

ΔΦ = (t + 1) + 2(m − 1) − (t + 2m)
    = t + 1 + 2m − 2 − t − 2m = −1

Read that as the debt being settled: the mark releases 2, the new tree keeps 1 of them as its own endowment, and the remaining 1 pays for the cutting work. Net −1 against an actual cost of 1, so the cut is free — exactly as the promise said it would be.

And if a mark were worth only 1?

Then the deposit covers only one of the two obligations. With Φ = t + m, the same cut gives:

Φbefore = t + m
Φafter  = (t + 1) + (m − 1) = t + m
ΔΦ = 0

The single unit released is entirely consumed by the new tree's endowment, leaving nothing for the cutting work. Every cut in a chain must then be paid out of pocket, so a DECREASE-KEY triggering c cascading cuts costs c — and c is unbounded. DECREASE-KEY would stop being O(1), and the whole reason for using a Fibonacci heap would be gone.

So 2 is forced, and 2 is enough. One unit per obligation, no more and no less — which is why the coefficient is exactly 2 and not 1, and equally not 3.

CSE3144 β€” Lecture 19 Β· Why the coefficient is 2
L19 Β· 09 β€” Why DECREASE-KEY is O(1): the common case ~3 min

First, the case that happens almost every time: one cut, one mark, no cascade

Most DECREASE-KEY calls set off no cascade at all. Getting this case right first makes the general one easy, because the cascade turns out to be the same accounting repeated.

Case A — the key still fits

The new key is still ≥ its parent's, or the node is already a root. Write the key in place, update min[H] if needed, and stop.

actual = 1    ΔΦ = 0    amortized = 1

No tree is created and no mark changes, so the potential does not move at all.

Case B — one cut, and the parent was unmarked

The key drops below the parent y, so the node is cut into the root list. Then CASCADING-CUT runs on y — and because y is unmarked, it simply marks y and returns. Nothing cascades.

Φbefore = t + 2m
Φafter  = (t + 1) + 2(m + 1)
ΔΦ = 1 + 2 = +3
actual = 1    amortized = 1 + 3 = 4 = O(1)

One more tree (+1) and one more mark (+2). The operation does one unit of work and banks three — a surcharge, not a refund.

What that deposit is for

Those 3 units are not wasted. The +1 covers the extra tree, which EXTRACT-MIN will later have to consolidate. The +2 is attached to the mark just created — and as L19·08a showed, two units is exactly what one future cascading cut costs. This operation is pre-paying for a cascade that has not happened yet, at the very node that will trigger it. The next slide spends that money.

CSE3144 β€” Lecture 19 Β· DECREASE-KEY cost, no cascade
L19 Β· 09a β€” Why DECREASE-KEY is O(1): with a cascade ~6 min

A longer cascade does more work β€” and releases proportionally more potential

Now the hard case. Let c be the number of CASCADING-CUT calls the operation makes. Case B above was simply c = 1. Here c can be any length, and the actual work grows with it — so the only question is whether the potential falls fast enough to keep up.

Interactive — count c, the cuts, and the marks, on one real cascade
Actual cost grows with c

One O(1) cut for the decreased node, plus one O(1) cut for each cascading step:

actual = O(1 + c) = O(c)

Taken alone this is bad news — c is not bounded by anything. A single DECREASE-KEY really can do a lot of work, as you saw when one call dissolved a whole tree.

Potential falls with c too

After the operation the heap holds t + c trees (the decreased node, plus one per cascading cut). Marks: every cascading cut but the last clears a mark, and the last call may set one — so at most m − c + 2 remain.

ΔΦ ≤ (t + c) + 2(m − c + 2) − (t + 2m)
    = c − 2c + 4 = 4 − c
amortized ≤ O(c) + (4 − c) = O(1)

The c's cancel. Every extra cut adds one unit of work and releases one unit of potential, so the length of the cascade drops out of the answer entirely.

Two sanity checks
  • The bound is tight at c = 1. Substituting c = 1 gives ΔΦ ≤ 3 — exactly the +3 computed on the previous slide. The no-cascade case is not a separate rule; it is this formula at its smallest c.
  • Against the run in L19·02c: that cascade made c = 4 calls. Trees went 4 → 8 = t + c ✓. Marks went 3 → 0, within the bound m − c + 2 = 1 ✓. And Φ fell 10 → 8, so ΔΦ = −2, comfortably inside 4 − c = 0 ✓.

Notice the sign flip: at c = 1 the operation banks potential (+3), and once c > 4 it spends it. That is the whole mechanism in one line — the cheap calls fund the expensive ones, and no single call is ever expensive on average.

CSE3144 β€” Lecture 19 Β· DECREASE-KEY cost, with cascade
L19 Β· 10 β€” Why EXTRACT-MIN is amortized O(log n) ~4 min

The potential drop refunds almost all of the consolidation work

Actual cost

Let D(n) = the largest degree any node can have in an n-node heap. Step 1 promotes the minimum's children into the root list — there are at most D(n) of them, so O(D(n)).

Step 2 consolidates, which walks the root list once. Count how long that list is when the sweep begins:

   t(H)  roots at the start
−    1  the minimum leaves
D(n)  its children arrive
—————————————
D(n) + t(H) − 1 roots

That −1 is simply the extracted node leaving. It is the value being returned, so it is no longer in the list to be walked over — its children take its place. Each remaining root is then checked in O(1), giving:

actual cost = O(D(n) + t(H))

The −1 disappears inside the O( ) and never affects the bound; it is worth seeing only so the count is honest. Verified in L19·04: 5 links across 6 initial roots, each O(1).

Potential change

Apply Φ to the heap before, and to the heap afterwards. Two facts pin down the "after" state: consolidation leaves at most one tree per degree, and degrees run 0, 1, …, D(n) — that is D(n) + 1 slots, so t can be no larger than that. (Verified in L19·04: 6 roots collapsed to just 1.) And marks can only fall during extract-min, never rise: a marked node loses its mark if it is linked as somebody's child, and nothing here sets one.

Φbefore = t(H) + 2m(H)
Φafter  = t(H′) + 2m(H′)
         ≤ (D(n) + 1) + 2m(H)

Subtracting, the mark terms disappear:

ΔΦ = Φafter − Φbefore
    ≤ [(D(n) + 1) + 2m(H)]
       − [t(H) + 2m(H)]
    = (D(n) + 1) − t(H)

The 2m(H) terms cancel outright — which is why marks play no part in this analysis at all. They matter only for DECREASE-KEY, where cascading cuts change them. Here the whole argument is about trees: t collapses from however large it had grown down to at most D(n)+1, and that collapse is the refund.

amortized = O(D(n)+t(H)) + (D(n)+1−t(H)) = O(D(n))

The t(H) terms cancel — however long the root list had grown from lazy inserts and cuts, the potential those operations banked pays for sweeping it. What survives is D(n) alone, and since D(n) = O(log n), the amortized cost is O(log n).

Two constants that look alike but mean different things

Each card above carries a small constant beside D(n), and they are easy to confuse. They come from different places:

whereexpressionwhat the constant means
actual workD(n) + t(H) − 1the minimum left the root list, so there is one fewer root to sweep
potential afterwardsD(n) + 1how many roots can survive: one per degree, and degrees 0 … D(n) inclusive is D(n)+1 slots

The first says one root is gone; the second says how many may remain. Neither changes the asymptotics — but mixing them up makes the derivation look arbitrary, which it is not.

CSE3144 β€” Lecture 19 Β· EXTRACT-MIN cost
L19 Β· 11 β€” Advantages & limitations ~5 min

The best known amortized bounds β€” and a real cost to get them

Advantages
  • DECREASE-KEY in Θ(1) amortized β€” the headline improvement over both binary and binomial heaps, verified today with a real cascading-cut example.
  • INSERT and UNION in Θ(1) amortized β€” both are pure root-list operations, no consolidation.
  • EXTRACT-MIN and DELETE stay O(log n) amortized β€” no regression versus binomial heaps, while everything else got strictly cheaper.
  • These are the asymptotically best known bounds for a mergeable priority queue with decrease-key β€” exactly why graph algorithms like Dijkstra's cite Fibonacci heaps as the theoretical optimum.
Limitations
  • Large constant factors in practice. The bookkeeping (parent/child/left/right/degree/mark per node, cascading-cut logic) often makes Fibonacci heaps slower in practice than a plain binary heap for the input sizes most real programs see β€” despite better asymptotics.
  • Genuinely intricate implementation. Circular doubly-linked lists at every level, plus the cascading-cut recursion, are meaningfully harder to implement correctly than a binary heap's single sift rule or even a binomial heap's four link cases.
  • EXTRACT-MIN's O(D(n)) bound relies on D(n) = O(log n) β€” a real theorem (proof omitted here, as in the source material), not an obvious fact; it depends on every tree of degree k having at least Fk+2 nodes (the Fibonacci numbers β€” hence the name).
  • No benefit if decrease-key is rare. If your workload is insert/extract-min only, a binary or binomial heap remains simpler with no real performance downside.
CSE3144 β€” Lecture 19 Β· Trade-offs
L19 Β· 12 β€” Complexity, all three heap families ~3 min

Binary vs. binomial vs. Fibonacci

OperationBinary heap (worst-case)Binomial heap (worst-case)Fibonacci heap (amortized)
MAKE-HEAPΘ(1)Θ(1)Θ(1)
INSERTΘ(log n)O(log n)Θ(1)
MINIMUMΘ(1)O(log n)Θ(1)
EXTRACT-MINΘ(log n)Θ(log n)O(log n)
MERGE/UNIONΘ(n)O(log n)Θ(1)
DECREASE-KEYΘ(log n)Θ(log n)Θ(1)
DELETEΘ(log n)Θ(log n)O(log n)

n = number of nodes at the time of the operation. Every Fibonacci-heap number above was exercised today with real, hand-traced examples β€” not just asserted.

CSE3144 β€” Lecture 19 Β· Complexity
L19 Β· 13 β€” Where this actually runs ~4 min

The theoretical benchmark for graph algorithms β€” with a practical asterisk

Dijkstra's shortest path

With a Fibonacci heap, Dijkstra's algorithm runs in O(E + V log V) β€” the E decrease-key calls (one per edge relaxed) cost O(1) amortized each, versus O(E log V) with a binary heap. This is the textbook headline result that motivates the whole structure.

Prim's minimum spanning tree

Same pattern: Prim's algorithm repeatedly decreases a vertex's "cheapest known connection" as better edges are found β€” exactly the decrease-key-heavy access pattern Fibonacci heaps are built for.

The practical asterisk

In practice, most production graph libraries use a plain binary heap or a simpler pairing heap (Lecture 20) instead β€” the constant-factor overhead of Fibonacci heaps' bookkeeping often outweighs the asymptotic win at realistic graph sizes. Fibonacci heaps remain essential for the theoretical result, even where they're rarely the implementation of choice.

CSE3144 β€” Lecture 19 Β· Real-world use
L19 Β· 14 β€” Recap & what's next ~4 min

Lazy now, tidy later β€” and the bill always comes out to O(1) or O(log n)

Lecture 20 β€” next

Pairing Heaps and Double-Ended Priority Queues

A structure almost as fast as Fibonacci heaps in theory, dramatically simpler in practice β€” and DEPQs, which support both extract-min AND extract-max.

Homework β€” bring to Lecture 20
  • Build a Fibonacci heap by inserting 5, 11, 2, 8. Union it with a second heap built from inserting 6, 14. Trace EXTRACT-MIN by hand, showing the degree array at every step.
  • On the heap resulting from the previous question, find a node with a grandparent and force a 2-level cascading cut via two decrease-key calls. Show the mark bits changing at each step.
  • In 3–4 sentences: why does the potential function weight marks by 2 and not by 1? What would break if it were 1?
  • In 3–4 sentences: explain, without any formulas, why Dijkstra's algorithm benefits more from a fast decrease-key than from a fast extract-min.
CSE3144 β€” Lecture 19

Questions?

Dr. Manu Shrivastava β€” LHC 308F β€” Friday 2:00–5:00 PM

Next: Lecture 20 β€” Pairing Heaps and Double-Ended Priority Queues.