codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🧮

Data Structures & Algorithms

34 / 65 topics
32Greedy Algorithms Basics33Activity Selection Problem34Huffman Coding35Fractional Knapsack Problem
Tutorials/Data Structures & Algorithms/Huffman Coding
🧮Data Structures & Algorithms

Huffman Coding

Updated 2026-04-20
4 min read

Huffman Coding

Huffman coding is a fundamental technique used in data compression, which falls under the category of greedy algorithms. It was developed by David A. Huffman in 1952 and is widely used for lossless data compression. The primary goal of Huffman coding is to represent data using variable-length codes, where more frequent characters are assigned shorter codes, thereby reducing the overall size of the encoded data.

Overview

Huffman coding operates on the principle of frequency analysis. It assigns shorter codes to more frequently occurring characters and longer codes to less frequently occurring ones. This approach ensures that the most common characters take up fewer bits in the final encoded output, thus achieving efficient compression.

Key Concepts

  1. Prefix Code: A prefix code is a type of code system where no code word is a prefix of any other code word. This property allows for unambiguous decoding of the encoded data.
  2. Greedy Algorithm: Huffman coding is a greedy algorithm because it makes a series of choices that are locally optimal at each step, with the hope of finding a global optimum.
  3. Binary Tree: The process of constructing Huffman codes involves building a binary tree where leaf nodes represent characters and internal nodes represent their combined frequencies.

Steps to Implement Huffman Coding

Step 1: Frequency Analysis

The first step in Huffman coding is to determine the frequency of each character in the input data. This can be done using a hash map or an array, depending on the character set size.

function calculateFrequency(data) {
    const frequencyMap = {};
    for (const char of data) {
        if (frequencyMap[char]) {
            frequencyMap[char]++;
        } else {
            frequencyMap[char] = 1;
        }
    }
    return frequencyMap;
}

Step 2: Build the Priority Queue

A priority queue is used to store nodes based on their frequencies. The node with the lowest frequency has the highest priority.

class MinHeap {
    constructor() {
        this.heap = [];
    }

    insert(node) {
        this.heap.push(node);
        let index = this.heap.length - 1;
        while (index > 0) {
            const parentIndex = Math.floor((index - 1) / 2);
            if (this.heap[parentIndex].frequency <= this.heap[index].frequency) break;
            [this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]];
            index = parentIndex;
        }
    }

    extractMin() {
        const min = this.heap[0];
        const end = this.heap.pop();
        if (this.heap.length > 0) {
            this.heap[0] = end;
            let index = 0;
            while (true) {
                let leftChildIndex = 2 * index + 1;
                let rightChildIndex = 2 * index + 2;
                let smallestIndex = index;

                if (leftChildIndex < this.heap.length && this.heap[leftChildIndex].frequency < this.heap[smallestIndex].frequency) {
                    smallestIndex = leftChildIndex;
                }
                if (rightChildIndex < this.heap.length && this.heap[rightChildIndex].frequency < this.heap[smallestIndex].frequency) {
                    smallestIndex = rightChildIndex;
                }

                if (smallestIndex === index) break;
                [this.heap[index], this.heap[smallestIndex]] = [this.heap[smallestIndex], this.heap[index]];
                index = smallestIndex;
            }
        }
        return min;
    }
}

Step 3: Construct the Huffman Tree

Using the priority queue, we repeatedly extract the two nodes with the lowest frequencies and combine them into a new node whose frequency is the sum of the two extracted nodes. This process continues until only one node remains in the priority queue, which becomes the root of the Huffman tree.

class Node {
    constructor(char, frequency) {
        this.char = char;
        this.frequency = frequency;
        this.left = null;
        this.right = null;
    }
}

function buildHuffmanTree(frequencyMap) {
    const minHeap = new MinHeap();
    for (const [char, frequency] of Object.entries(frequencyMap)) {
        minHeap.insert(new Node(char, frequency));
    }

    while (minHeap.heap.length > 1) {
        const left = minHeap.extractMin();
        const right = minHeap.extractMin();
        const newNode = new Node(null, left.frequency + right.frequency);
        newNode.left = left;
        newNode.right = right;
        minHeap.insert(newNode);
    }

    return minHeap.extractMin();
}

Step 4: Generate Huffman Codes

Once the Huffman tree is constructed, we traverse the tree to generate Huffman codes for each character. A left edge in the tree represents a '0', and a right edge represents a '1'.

function generateCodes(root, code = "", codeMap = {}) {
    if (root.char) {
        codeMap[root.char] = code;
        return;
    }
    if (root.left) generateCodes(root.left, code + "0", codeMap);
    if (root.right) generateCodes(root.right, code + "1", codeMap);
    return codeMap;
}

Step 5: Encode the Data

Using the generated Huffman codes, we can encode the input data.

function encodeData(data, codeMap) {
    let encodedData = "";
    for (const char of data) {
        encodedData += codeMap[char];
    }
    return encodedData;
}

Step 6: Decode the Data

To decode the encoded data back to its original form, we traverse the Huffman tree based on the bits in the encoded string.

function decodeData(encodedData, root) {
    let decodedData = "";
    let currentNode = root;

    for (const bit of encodedData) {
        if (bit === "0") {
            currentNode = currentNode.left;
        } else {
            currentNode = currentNode.right;
        }
        if (currentNode.char) {
            decodedData += currentNode.char;
            currentNode = root;
        }
    }

    return decodedData;
}

Example

Let's walk through an example to illustrate the Huffman coding process.

Input Data

Consider the string "this is an example for huffman encoding".

  1. Frequency Analysis:

    • t: 2, h: 2, i: 2, s: 4, a: 1, n: 3, e: 5, x: 1, m: 2, p: 1, l: 1, f: 1, o: 1, r: 1, u: 1, c: 1, g: 1
  2. Build the Priority Queue:

    • Insert nodes into the priority queue based on their frequencies.
  3. Construct the Huffman Tree:

    • Combine nodes with the lowest frequencies until only one node remains.
  4. Generate Huffman Codes:

    • Traverse the tree to generate codes for each character.
  5. Encode the Data:

    • Use the generated codes to encode the input string.
  6. Decode the Data:

    • Traverse the tree based on the encoded bits to decode the data back to its original form.

Best Practices

  1. Character Set Size: Huffman coding is most effective for character sets with a wide range of frequencies.
  2. Efficiency: The time complexity of building the Huffman tree is \(O(n \log n)\), where \(n\) is the number of unique characters.
  3. Adaptability: While Huffman coding is static, adaptive Huffman coding can be used to handle dynamic data streams.

Conclusion

Huffman coding is a powerful technique for lossless data compression that leverages frequency analysis and greedy algorithms. By assigning shorter codes to more frequent characters, it achieves significant reductions in the size of encoded data. Understanding and implementing Huffman coding provides valuable insights into efficient data compression strategies, which are essential in various applications such as file compression, image processing, and telecommunications.

By following the steps outlined in this tutorial, you can implement Huffman coding from scratch and apply it to real-world scenarios.


PreviousActivity Selection ProblemNext Fractional Knapsack Problem

Recommended Gear

Activity Selection ProblemFractional Knapsack Problem