Memra

Huffman codes

◈ 5 cards

Optimal prefix-free codes built greedily by repeatedly merging the two lowest-frequency nodes with a min-priority queue, in O(n lg n).

Prefix-free codes

To compress a file we give each character a binary codeword and concatenate them. A prefix-free code (a.k.a. prefix code) is one where no codeword is a prefix of another. That guarantees unambiguous decoding: scan bits left to right, and the moment they match a codeword you have found that character — no backtracking needed.

Every prefix-free code is a full binary trie whose leaves are the characters: a left edge is a 0, a right edge is a 1, and a character's codeword is the path from the root to its leaf. The codeword length equals the leaf's depth.

Cost of a code

For a tree over alphabet with frequencies , the number of bits to encode the whole file is

where is the depth of 's leaf (its codeword length). An optimal code minimizes , so frequent characters should sit shallow (short codewords) and rare ones deep.

Worked example. With frequencies (in thousands) (CLRS Fig. 15.4), Huffman gives a length-1 codeword and length 3, length 4, so

A 3-bit fixed-length code would cost — Huffman saves about 25%.

The greedy algorithm

Put every character into a min-priority queue keyed by frequency. Then repeat times: extract the two lowest-frequency nodes and , make a new internal node with and children , and insert . The last node left is the root.

Building the heap is ; each of the iterations does two EXTRACT-MINs and one INSERT at each, so the total is .

Why it is optimal (exchange argument again). Lemma 15.2 (greedy choice): the two lowest-frequency characters can be made sibling leaves at maximum depth in some optimal tree — swap them down toward the deepest leaves; since they have the smallest frequencies, moving them deeper cannot increase . Lemma 15.3 (optimal substructure): merging into a node of frequency yields a smaller alphabet whose optimal tree, with re-expanded, is optimal for the original. Induction over the merges proves Huffman optimal.

01100roota:45001550125c:12100b:1310101300114f:51100e:91101d:16111
Left edge = 0, right edge = 1; a codeword is the root-to-leaf path, so its length is the leaf depth. The frequent a sits at depth 1, the rare e and f at depth 4.
steptwo smallestnew nodequeue after(freqs)1f:5, e:91412 13 14 16 452c:12, b:132514 16 25 45314, d:163025 30 45425, 305545 555a:45, 55100root onlyStart queue: 5 9 12 13 16 45. Merging the two rarest characters first is what pushes them deepest,giving them the longest codewords.
Every step is two EXTRACT-MINs and one INSERT — n − 1 = 5 merges build the tree bottom-up.
NORMAL ~/memra/learn/comp-372/huffman-codes utf-8 LF