Yasir Explains/Algorithms/Greedy Algorithms/Huffman Codes
Greedy Algorithms

Huffman Codes

On this page

Why Huffman Coding?The Greedy StrategyStep-by-Step Huffman CodingEncodingDecodingPseudocodeComplexity AnalysisInteractive Playground
Greedy Algorithms

Huffman Codes

Build optimal prefix-free codes using a greedy, bottom-up tree construction.

Why Huffman Coding?

In a fixed-length encoding, every character uses the same number of bits (e.g., ASCII uses 8 bits per character). Huffman coding assigns variable-length codes: frequent characters get shorter codes, rare characters get longer ones. This can dramatically reduce total encoding size.

Huffman codes are prefix-free: no code is a prefix of another, allowing unambiguous decoding.

The Greedy Strategy

  1. Build a frequency table for all characters
  2. Create a leaf node for each character
  3. Repeatedly merge the two lowest-frequency nodes into a new internal node (sum of frequencies)
  4. The final tree defines the encoding: left edges = 0, right edges = 1

This is greedy because at each step we merge the two cheapest nodes, minimizing the total encoding cost from the bottom up.

Step-by-Step Huffman Coding

The visualization follows the full pipeline: an input string, the frequency table from counting symbols, then greedy merges. During construction the forest (every subtree currently in the priority queue) stays on screen at all times—two smallest trees are highlighted when extracted, then merged and re-inserted. The last step shows the final tree and prefix codes.

1 · Input string

String

abacddaeacbdeabcadabcdce

Input string to compress. Next we count symbol frequencies.
1 / 12
Speed

Encoding

Encoding walks the plaintext left to right. For each character, look up its bit sequence in the Huffman table (from the tree) and append those bits to the stream. Frequent symbols contribute fewer bits per occurrence, so the total length can be much smaller than a fixed-width code.

This uses the same input string as Step-by-Step Huffman Coding above. Step through to see each symbol replaced and the bitstream grow.

Huffman encoding

Plaintext (symbol highlighted while it is encoded)

abacddaeacbdeabcadabcdce

Code table

c→00
d→01
a→10
e→110
b→111

Bitstream (grows left to right)

…
Encoding table from the Huffman tree. Each character will be replaced by its bit sequence.
1 / 26
Speed

Decoding

Decoding uses the same tree. Start at the root; for each incoming bit, go left on 0 and right on 1. When you hit a leaf, output that symbol and jump back to the root. Prefix-free codes ensure you never need lookahead.

The bitstream is exactly what Huffman encoding produces for the same string as in Step-by-Step Huffman Coding, so stepping through recovers the original plaintext.

Huffman decoding

Code bits (read left to right; consumed portion highlighted)

1011110000101101101000111011101011100100110111000100110

Decoded output

…

Tree traversal

00110101○24○10c5d5○14a7○7e3b4
Start at the root. Read bits: 0 = left, 1 = right, until you reach a leaf.
1 / 81
Speed

Pseudocode

The algorithm uses a min-priority queue (min-heap) and runs in O(n log n) time.

1HUFFMAN(C)
2 n = |C|
3 Q = min-priority queue of C // keyed by frequency
4 for i = 1 to n - 1
5 z = new node
6 z.left = x = EXTRACT-MIN(Q)
7 z.right = y = EXTRACT-MIN(Q)
8 z.freq = x.freq + y.freq
9 INSERT(Q, z)
10 return EXTRACT-MIN(Q) // root of tree

Complexity Analysis

Building the initial heap is O(n). Each of the (n-1) merge operations involves two extract-min and one insert, each O(log n). Total: O(n log n).

Complexity Analysis

Time Complexity

O(n log n)

Space Complexity

O(n)

n-1 merges, each with O(log n) heap operations

Growth Rate Comparison

n (input size)O(1)O(log n)O(n)O(n log n)O(n²)

Interactive Playground

Enter a string or frequency table to build a custom Huffman tree. Compare the encoded size against fixed-length encoding.

1 · Input string

String

abacddaeacbdeabcadabcdce

Input string to compress. Next we count symbol frequencies.
1 / 12
Speed