| # | Action | Nodes | Result |
|---|---|---|---|
| 4 | extract | c | 0 merges |
| 5 | extract | + d | 0 merges |
| 6 | merge | c + d | 1 merges |
| 7 | merge | 1 merges | |
| 8 | merge | 1 merges | |
| 9 | insert | 1 merges | |
| 10 | check | 1 merges | |
| 11 | extract | _merge1 | 1 merges |
| 12 | extract | + b | 1 merges |
| 13 | merge | _merge1 + b | 2 merges |
| 14 | merge | 2 merges | |
| 15 | merge | 2 merges | |
| 16 | insert | 2 merges | |
| 17 | check | 2 merges | |
| 18 | extract | r | 2 merges |
| 19 | extract | + _merge2 | 2 merges |
| 20 | merge | r + _merge2 | 3 merges |
| 21 | merge | 3 merges | |
| 22 | merge | 3 merges | |
| 23 | insert | 3 merges | |
| 24 | check | 3 merges | |
| 25 | extract | a | 3 merges |
| 26 | extract | + _merge3 | 3 merges |
| 27 | merge | a + _merge3 | 4 merges |
| 28 | merge | 4 merges | |
| 29 | merge | 4 merges | |
| 30 | insert | 4 merges | |
| 31 | done | 4 merges | |
| 32 | codes | 4 merges | |
| 33 | done | 4 merges |
| Char | Freq | Code | Bits | Fixed (8-bit) |
|---|---|---|---|---|
| c | 1 | 1100 | 4 | 8 → 4 (50% less) |
| d | 1 | 1101 | 4 | 8 → 4 (50% less) |
| b | 2 | 111 | 3 | 16 → 6 (63% less) |
| r | 2 | 10 | 2 | 16 → 4 (75% less) |
| a | 5 | 0 | 1 | 40 → 5 (88% less) |
| Algorithm | Best Case | Average Case | Worst Case | Space |
|---|---|---|---|---|
| Huffman Coding | O(n log n) | O(n log n) | O(n log n) | O(n) |
| Shannon-Fano | O(n log n) | O(n log n) | O(n²) | O(n) |
| Arithmetic Coding | O(n) | O(n) | O(n) | O(n) |
Huffman Coding is a lossless data compression algorithm invented by David A. Huffman in 1952. It assigns variable-length binary codes to characters based on their frequency of occurrence.
Characters that appear more often get shorter codes; rare characters get longer codes. This is the opposite of fixed-length encoding (e.g., ASCII uses 8 bits per character regardless of frequency).
When to use it:
- Compressing text files (used in ZIP, GZIP)
- Image compression (JPEG uses Huffman as a final step)
- Any scenario where symbol frequencies vary greatly
Key property:
Huffman codes are prefix-free: no code is a prefix of another, so they can be decoded unambiguously without separators.
Step-by-step:
- 1. Count frequencies of each character in the input.
- 2. Build a min-heap (priority queue) of leaf nodes, one per character.
- 3. Repeat until one node remains:
- Extract the two nodes with minimum frequency (extract-min twice).
- Create a new internal node with their sum as frequency.
- Insert the new node back into the heap.
- 4. The remaining node is the root of the Huffman tree.
- 5. Assign codes: traverse from root; left edge = 0, right edge = 1.
Complexity:
With a binary min-heap: O(n log n) where n = number of distinct characters. Each of the n-1 merge steps requires two extract-min (O(log n)) and one insert (O(log n)).
Frequencies:
a=5, b=2, r=2, c=1, d=1
Heap initially:
[c:1, d:1, b:2, r:2, a:5]
Step 1 — Merge c:1 and d:1:
New node cd:2. Heap: [b:2, r:2, cd:2, a:5]
Step 2 — Merge b:2 and r:2:
New node br:4. Heap: [cd:2, a:5, br:4]
Step 3 — Merge cd:2 and br:4:
New node cdbr:6. Heap: [a:5, cdbr:6]
Step 4 — Merge a:5 and cdbr:6:
Root: 11. Tree complete!
Resulting codes:
a=0, b=110, r=111, c=100, d=101
Total bits = 5×1 + 2×3 + 2×3 + 1×3 + 1×3 = 23 bits vs 11×8 = 88 bits fixed