Introduction
Huffman coding builds an optimal prefix code for a set of symbols with known frequencies: no codeword is a prefix of another, so a bit stream decodes uniquely without separators, and the expected codeword length is minimised among all binary prefix codes.
The construction is a textbook greedy algorithm: repeatedly merge the two lightest trees. The same merge pattern also solves optimal merge patterns (combine sorted files of given lengths at minimum total cost). Both belong to the greedy part of the syllabus and reuse a binary heap as the priority queue.
Prerequisites
- Greedy Algorithms: greedy-choice property and optimal substructure.
- Binary Heaps: extract-min and insert in .
- Full binary trees: every node has 0 or 2 children (needed for the optimality argument).
Core concepts
Prefix codes
A code is prefix-free (a prefix code) when no codeword is a prefix of another. Equivalently, the codewords are the root-to-leaf paths of a binary tree whose leaves are the symbols (left = 0, right = 1, or the reverse). Fixed-length codes are prefix-free but usually longer than necessary when frequencies are skewed.
The cost of a tree for frequencies is
where is the depth of leaf (edge count). is the total number of bits used to encode a file whose symbol counts are the values.
Full trees only
An optimal prefix code corresponds to a full binary tree: every internal node has exactly two children. A node with one child can be bypassed, shortening every codeword in that subtree and lowering .
Optimal merge patterns
Given sorted runs of lengths , merging two runs of lengths and costs . The total cost of a binary merge tree equals the sum, over every internal node, of the combined size of its two children, which is the same formula as with . So Huffman’s construction also yields an optimal merge order.
Algorithms and pseudocode
Pseudocode uses 1-based arrays, <- for assignment and a min-priority queue Q of trees keyed by freq.
HUFFMAN(C)
1 n <- |C|
2 Q <- C // min-priority queue on freq
3 for i <- 1 to n - 1
4 allocate a new node z
5 z.left <- x <- EXTRACT-MIN(Q)
6 z.right <- y <- EXTRACT-MIN(Q)
7 z.freq <- x.freq + y.freq
8 INSERT(Q, z)
9 return EXTRACT-MIN(Q) // the rootInput. A set of symbols, each with a positive frequency freq.
Output. The root of an optimal Huffman tree.
Time. With a binary heap, each of the iterations does two extract-mins and one insert: . Building the initial heap is . Space for the tree nodes.
Counting facts. The loop runs exactly times, so the tree has leaves, internal nodes, nodes in all and edges. The queue sees EXTRACT-MIN calls inside the loop (plus the final one) and INSERT calls. If the frequencies arrive already sorted, two FIFO queues (one for the original leaves, one for the merged nodes, whose keys come out in nondecreasing order) give an construction.
Edge cases. : one merge, codewords 0 and 1. Equal frequencies: any tie-breaking among equal keys is allowed; different trees may arise, but all are optimal. Zero frequency is excluded (a zero-frequency symbol can be dropped before coding).
Mathematical explanation
Greedy-choice property
Lemma (CLRS 3e, Section 16.3). Let and be two symbols of lowest frequency. There exists an optimal prefix code in which the codewords for and have the same length and differ only in the last bit (they are siblings in the tree).
Idea. Order the two minimum frequencies as . Choose deepest sibling leaves , ordered so . After resolving coincident symbols by relabelling, and . Move the lower-frequency symbols to those deeper positions by exchanges. Each exchange changes cost by , or the analogous expression for . Thus an optimal tree exists with deepest siblings.
Optimal substructure
Replace and by a single symbol of frequency . An optimal tree for the reduced alphabet, expanded by making and the children of , is optimal for the original alphabet. The cost increases by exactly (one extra bit on every occurrence of or ).
Together, the two properties justify the algorithm: each merge is a safe greedy choice, and the residual problem is again a Huffman instance.
Equivalent cost formula
where is the sum of the frequencies of the leaves in 's subtree (equivalently, the sum of the frequencies of 's two children). This matches the total merge cost in an optimal merge pattern.
Worked examples
Five symbols
Frequencies: , , , , .
| Step | Extract | New node freq | Queue keys (ascending) |
|---|---|---|---|
| start | 9, 12, 13, 16, 45 | ||
| 1 | , | 13, 16, 21, 45 | |
| 2 | , | 21, 29, 45 | |
| 3 | , | 45, 50 | |
| 4 | , | root | 95 |
Codewords (left = 0, right = 1; children ordered as extracted):
| Symbol | Path | Codeword | Length |
|---|---|---|---|
| left of root | 0 | 1 | |
| right-left-left | 100 | 3 | |
| right-left-right | 101 | 3 | |
| right-right-left | 110 | 3 | |
| right-right-right | 111 | 3 |
At the root, (extracted first in step 4) is the left child and the right; inside , is left and right. The exact bit strings depend on this left/right convention; the lengths do not. Weighted external path length:
Check via internal nodes: .

Optimal merge of four files
Lengths 20, 30, 10, 25. Merges:
- (cost 30); remaining 25, 30, 30.
- (cost 55); remaining 30, 55.
- (cost 85).
Total cost . The cost depends only on which runs end up merged together (the shape of the merge tree), not on the order in which independent merges are carried out. Merging the two largest first (30 with 25, then 55 with 20, then 75 with 10) costs , which is worse.
Decoding a bit string
With the code of the five-symbol example (, , , , ), decode 1100101111. Walk from the root and restart at the root at each leaf: 110 gives , 0 gives , 101 gives , 111 gives . The message is . No separators are needed because no codeword is a prefix of another.
Ties can change the codeword lengths
Frequencies (symbols ). The first merge is forced: . Now three keys equal 2 (the new node and , ).
- Merge with : lengths , cost .
- Merge the new node with : lengths , cost .
Both trees are optimal, but the maximum codeword length (2 versus 3) and the set of lengths differ. A question that asks for "the" length of a symbol must fix a tie-breaking rule.
Average length against entropy
With probabilities , the average length of an optimal prefix code satisfies , where is the entropy (in bits per symbol). For the five-symbol example, and .
Important properties and observations
- Huffman codes are optimal among all binary prefix codes. By the Kraft-McMillan inequality (), any uniquely decodable code's lengths can be met by a prefix code, so Huffman is also optimal among all uniquely decodable symbol-by-symbol codes. An optimal (full) tree satisfies exactly.
- The longest codeword can have length . Fibonacci-like frequencies build a completely skewed tree: the two 1s get length 7 and 21 gets length 1.
- The code is not unique: swapping left and right children, or breaking frequency ties differently, changes bit strings but not .
- Average codeword length is . For the example, bits per symbol, against for a fixed-length code.
- If one frequency exceeds the sum of all the others, that symbol is merged last and gets a 1-bit codeword. The condition is sufficient, not necessary: is below yet still gets length 1 above.
- Alphabet size 1. A single symbol needs zero payload bits only if the message length is supplied out of band; otherwise use, for example, the one-bit codeword 0 per occurrence with suitable message framing; the algorithm assumes .
Common misconceptions.
- "Huffman always beats a fixed-length code." With all frequencies equal and a power of 2, every codeword has length , exactly a fixed-length code. For other , lengths are and : five equal frequencies give lengths , average 2.4 bits against 3.
- "Any greedy merge of files is optimal." Only repeatedly merging the two currently shortest runs is guaranteed; other orders can cost more.
- "Each symbol's codeword length is fixed." Only the cost is fixed. Tie-breaking can change both individual lengths and the maximum length, as the example shows.
GATE examination perspective
- TRACE THE HEAP. Questions give frequencies and ask for the next merge, the final , or a codeword length.
- INTERNAL-NODE SUM. Computing as the sum of internal-node frequencies is faster than walking every leaf.
- TIES. State how ties are broken; lengths stay optimal either way.
- MERGE PATTERNS. Same algorithm, cost = sum of merge sizes; do not confuse with the final combined file size alone.
- PREFIX PROPERTY. Instant decode: reading bits walks the tree until a leaf.
- COUNTS. symbols give merges, internal nodes and nodes. The longest codeword is at most bits.
- AVERAGE LENGTH. Divide by the total frequency (or use probabilities directly). Compare with for "bits saved" questions.
- MERGE COST MODEL. Merge-pattern cost counts records moved ( per merge). Merging two sorted runs needs at most comparisons; read which quantity the question wants.
Summary
Sources
- T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Introduction to Algorithms, 3rd ed., MIT Press, 2009: Chapter 16, Section 16.3 (Huffman codes).