Small Group Tutorials

Here to help students catch up, keep up, and move ahead. Book a consultation here.

How to Learn the Garsia–Wachs Algorithm: Alphabetic Binary Trees, Weighted Path Length, Ordered Leaves and O(n log n) Construction

Three students studying together in an eduKate small-group classroom.

What if the cheapest binary tree is not allowed to rearrange its leaves? That single restriction turns ordinary Huffman-style thinking into a deeper algorithmic problem. The Garsia–Wachs algorithm constructs an optimal binary leaf tree when the leaf order must remain fixed, while still minimizing weighted path length.

This Learning Hall article develops Garsia–Wachs from visible tree costs to the three-phase construction, correctness ideas, implementation choices and professional uses. It complements the broader Data Compression Algorithms learning article; it does not take over that wider compression job.

Quick Read

  • Input: an ordered sequence of non-negative leaf weights.
  • Output: a full binary tree whose leaves appear in exactly that order.
  • Objective: minimize the weighted sum of leaf depths.
  • Ordinary Huffman coding may freely permute symbols; an alphabetic tree may not.
  • Garsia–Wachs solves the ordered problem in O(n log n) time with an appropriate data structure.
  • The algorithm is best understood as three stages: build an auxiliary tree, extract leaf depths, then reconstruct an ordered tree with those depths.
  • The professional lesson is that a global ordering constraint can change the right greedy structure without destroying optimality.

1. Beginner Level: The Cost of a Binary Leaf Tree

Suppose four leaves have weights 6, 2, 3 and 7. If a leaf is one edge below the root, its depth is 1. If it is three edges below, its depth is 3. The weighted path length is:

cost = sum(weight[i] * depth[i])

A heavier leaf is expensive when placed deep in the tree. That immediately suggests a useful intuition: frequent or important leaves should tend to be shallow. But the order condition matters. If the leaves must remain 6, 2, 3, 7 from left to right, we cannot simply move 7 wherever a Huffman merge happens to place it.

2. Why Ordinary Huffman Coding Is Not Enough

Huffman coding repeatedly combines the two smallest weights. That rule is optimal when only code lengths matter and the symbols may be arranged freely in the tree. An alphabetic code adds another contract: lexicographic order of the symbols must agree with left-to-right leaf order.

This occurs when order itself carries meaning: ordered search intervals, alphabetic prefix codes, comparison structures and some rope or sequence-balancing problems. The algorithm is therefore not “Huffman with a small tweak.” The feasible set of trees is different.

3. The Problem Statement Precisely

Given weights w0, w1, …, wn in fixed order, construct a full binary tree with exactly n+1 leaves such that:

  • leaf i appears before leaf j whenever i < j;
  • every internal node has two children; and
  • the sum of wi × depth(i) is as small as possible.

That objective can also be interpreted as expected search cost when the weights are access probabilities or frequencies. The algorithmic job is therefore an ordered optimisation problem over tree shapes.

4. The Three-Phase Notional Machine

The clearest mental model separates the algorithm into three jobs.

  • Phase A — combine: build an auxiliary binary tree using a special sequence rule. The auxiliary tree may not yet respect the required leaf order.
  • Phase B — measure: record the depth assigned to each original leaf.
  • Phase C — rebuild: construct an alphabetically ordered tree whose leaves have those same depths.

This separation is important for learning. The first phase discovers the optimal multiset of depths. The last phase restores the order constraint without changing those depths, and therefore without changing weighted path length.

5. Phase A: Sentinels and the Compatible Triple Rule

Start with the leaf weights and place an infinite sentinel at each end. Repeatedly scan for the first three consecutive finite-or-sentinel values x, y, z satisfying:

x <= z

Then combine x and y into a parent of weight x+y. Remove x and y from the sequence. Reinsert the new weight immediately after the rightmost earlier value that is at least x+y.

The sentinels are not decorative. The right sentinel guarantees that a compatible triple will eventually be found; the left sentinel guarantees a legal reinsertion point.

6. A Small Trace

Use weights [6, 2, 3, 7]. Add sentinels:

∞, 6, 2, 3, 7, ∞

The triple 6,2,3 does not qualify because 6 ≤ 3 is false. The next triple 2,3,7 does qualify. Merge 2 and 3 to obtain 5, then reinsert 5 after the rightmost earlier value at least 5. That leaves:

∞, 6, 5, 7, ∞

Now 6,5,7 qualifies, so 6 and 5 combine to 11. Finally 11 and 7 combine. The auxiliary tree assigns depths 2,3,3,1 to the four original leaves, giving weighted cost:

6*2 + 2*3 + 3*3 + 7*1 = 34

On easy examples the auxiliary tree may already have the correct leaf order. Do not rely on that. The general algorithm explicitly separates depth discovery from ordered reconstruction.

7. Educational Pseudocode for the Combine Phase

forest = leaves_with_weights(weights)
sequence = [INF] + forest + [INF]

while more_than_one_real_tree(sequence):
    find first consecutive x, y, z with weight(x) <= weight(z)
    parent = node(x, y, weight(x) + weight(y))
    remove x and y
    find rightmost earlier position p with weight(p) >= weight(parent)
    insert parent immediately after p

auxiliary_tree = the_remaining_real_tree

This is a learning model, not yet the O(n log n) implementation. A naive list can make reinsertion linear and push the overall running time toward O(n²). The professional algorithm uses structure in the sequence to locate reinsertion efficiently.

8. Phase B: Depths Are the Valuable Output of the Auxiliary Tree

After the combine phase, traverse the auxiliary tree and record the depth of every original leaf. The crucial theorem behind Garsia–Wachs is that these depths can be realised by another full binary tree whose leaves are restored to the original order, and that this ordered tree is optimal.

This is the moment where many learners make a conceptual jump: the exact parent-child structure found in Phase A is not sacred. The depth assignment is what carries the optimal cost into the final tree.

9. Phase C: Reconstruct an Ordered Tree

The final reconstruction uses the original left-to-right leaf order together with the computed depths. Production descriptions often implement this in linear time once the depth sequence is known. The reconstruction must satisfy two invariants simultaneously: the leaves remain in original order, and each leaf receives the prescribed depth.

For study, separate the proof obligation from the mechanics. First verify a candidate tree preserves the order. Then verify its leaf-depth sequence matches the auxiliary tree. If both are true, the weighted cost is unchanged.

10. Why the Algorithm Is Correct — The Intuition

The full proof is subtle. The important learning route is to build three ideas before reading the formal argument:

  • the objective depends only on weights and leaf depths, not on internal-node labels;
  • the combine rule preserves structural properties that an optimal alphabetic tree can be assumed to satisfy; and
  • the depth sequence produced by the auxiliary process can be realised in the required order.

Later correctness work by Karpinski, Larmore and Rytter gave cleaner ways to reason about the structure of optimal alphabetic trees. For a professional reader, that is a useful reminder that an algorithm can be stable for decades while its best explanation continues to improve.

11. Complexity: Where O(n log n) Comes From

There are n combine operations. If the sequence is represented so that deletion and reinsertion take O(log n), the combine phase is O(n log n). The depth extraction and final reconstruction can be linear. The resulting asymptotic time is O(n log n), with linear-sized storage.

A simple list implementation is pedagogically useful but not asymptotically optimal. Richard Bird’s 2020 functional treatment is particularly valuable because it makes the hidden sequence property explicit: the maintained weights form a two-sorted structure that can support faster splitting and insertion.

12. The Professional Data-Structure Question

The mathematical algorithm and the engineering representation are separate decisions. A robust implementation must decide how to support:

  • ordered sequence access;
  • finding the next compatible triple;
  • removing adjacent trees;
  • searching backward for the reinsertion boundary;
  • storing subtree identity while weights move; and
  • recovering original leaf identities for the final depth sequence.

Balanced trees, specialised sequence structures or carefully exploited two-sorted representations can all be appropriate. The correct choice depends on language, memory model and whether the implementation needs only optimal cost, the final tree, or persistent intermediate states.

13. Common Misconceptions

  • “It is just Huffman coding.” No. Huffman coding does not preserve a predetermined leaf order.
  • “Always merge the two smallest adjacent weights.” That is not the Garsia–Wachs rule.
  • “The auxiliary tree is the final tree.” Not in general; its depths are the transferable asset.
  • “O(n log n) happens automatically.” A naive reinsertion structure can make the implementation quadratic.
  • “Any optimal depth multiset can be assigned to the leaves arbitrarily.” Ordered reconstruction must satisfy tree feasibility and original order.
  • “Equal weights are trivial.” Ties can create multiple optimal trees, so deterministic tie policy is useful for testing and reproducibility.

14. When Would a Professional Use It?

Garsia–Wachs is relevant when order must survive optimisation. Examples include alphabetic prefix codes, ordered decision trees and specialised sequence structures where weighted access cost matters. It is also an excellent training algorithm because it exposes a sophisticated pattern: optimise in a relaxed representation, preserve the cost-defining invariant, then reconstruct a feasible solution.

It is usually not the default choice for ordinary compression pipelines, where Huffman, arithmetic coding or modern entropy coders have different operational goals. Professional algorithm choice begins with the contract, not with the elegance of the method.

15. A Beginner-to-Professional Learning Ladder

  • Beginner: calculate weighted path length for several hand-drawn trees and explain why leaf order changes the feasible set.
  • Intermediate: trace the sentinel-and-combine phase and explain every reinsertion.
  • Advanced: implement a clear O(n²) reference version, extract depths, and compare its cost with brute force for tiny n.
  • Professional: implement an O(n log n) sequence structure, prove invariants, define tie behaviour, stress-test against exhaustive optimal trees, and benchmark realistic weight distributions.

16. Practice Problems

  • Draw every full ordered binary tree for four leaves and find the minimum weighted path length for [1,2,3,4].
  • Trace the combine phase for [4,1,1,4] and record every sequence state.
  • Write a brute-force ordered-tree solver for n ≤ 8 and use it as an oracle.
  • Construct an example where ordinary Huffman coding gives an arrangement that violates the required alphabetic order.
  • Measure how often a naive list implementation shifts elements during reinsertion.
  • Explain why preserving leaf depths preserves total cost.
  • Compare the conceptual roles of Garsia–Wachs and Package-Merge: both optimise code lengths under constraints, but the constraints are different.

17. Sources and Further Reading

Final idea: Garsia–Wachs is not valuable because everyone needs alphabetic codes every day. It is valuable because it teaches a professional habit of mind: when a constraint blocks an obvious greedy algorithm, identify exactly what determines cost, preserve that invariant through a more flexible intermediate representation, and reconstruct a solution that satisfies the real-world constraint.