简体   繁体   中英

Huffman code Explanation Java

I'm new in java and I'm trying to understand Huffman coding by using a code online. I'm messing with the code to understand how it works cause I did not find anything on how to implement a Huffman code. I need to understand why in this code the guy used comparable in Huffman tree class and string buffer. If someone knows any good explanation of Huffman coding online or even an algorithm, please. I really need to understand this code. PS: English is not my native language so sorry for any confusion. Thank you

import java.util.*;

public class HuffmanCode {
    // input is an array of frequencies, indexed by character code
    public HuffmanTree buildTree(int[] charFreqs) {
        PriorityQueue<HuffmanTree> trees = new PriorityQueue<HuffmanTree>();
        // initially, we have a forest of leaves
        // one for each non-empty character
        for (int i = 0; i < charFreqs.length; i++)
            if (charFreqs[i] > 0)
                trees.offer(new HuffmanLeaf(charFreqs[i], (char)i));

        assert trees.size() > 0;
        // loop until there is only one tree left
        while (trees.size() > 1) {
            // two trees with least frequency
            HuffmanTree a = trees.poll();
            HuffmanTree b = trees.poll();

            // put into new node and re-insert into queue
            trees.offer(new HuffmanNode(a, b));
        }
        return trees.poll();
    }

    public void printCodes(HuffmanTree tree, StringBuffer prefix) {
        assert tree != null;
        if (tree instanceof HuffmanLeaf) {
            HuffmanLeaf leaf = (HuffmanLeaf)tree;

            // print out character, frequency, and code for this leaf (which is just the prefix)
            System.out.println(leaf.value + "\t" + leaf.frequency + "\t" + prefix);

        } else if (tree instanceof HuffmanNode) {
            HuffmanNode node = (HuffmanNode)tree;

            // traverse left
            prefix.append('0');
            //prefix = prefix + "0";
            printCodes(node.left, prefix);
            prefix.deleteCharAt(prefix.length()-1);

            // traverse right
            prefix.append('1');
            printCodes(node.right, prefix);
            prefix.deleteCharAt(prefix.length()-1);
        }
    }
}

Huffman tree class:

public class HuffmanTree implements Comparable<HuffmanTree> {
    public final int frequency; // the frequency of this tree

    public HuffmanTree(int freq) {
        frequency = freq;
    }

    // compares on the frequency
    public int compareTo(HuffmanTree tree) {
        return frequency - tree.frequency;
    }
}

Huffman leaf:

class HuffmanLeaf extends HuffmanTree {

    public final char value; // the character this leaf represents

    public HuffmanLeaf(int freq, char val) {
        super(freq);
        value = val;
    }
}

Huffman node:

class HuffmanNode extends HuffmanTree {

    public final HuffmanTree left, right; // subtrees

    public HuffmanNode(HuffmanTree l, HuffmanTree r) {
        //Calling the super  constructor HuffmanTree 
        super(l.frequency + r.frequency);
        left = l;
        right = r;
    }

}

Main:

public class Main {

    public static void main(String[] args) {
        String test = "Hello World";
        HuffmanCode newCode = new HuffmanCode();

        // we will assume that all our characters will have
        // code less than 256, for simplicity
        int[] charFreqs = new int[256];
        // read each character and record the frequencies
        for (char c : test.toCharArray())
            charFreqs[c]++;

        // build tree
        ////HuffmanTree tree = buildTree(charFreqs);
        HuffmanTree tree = newCode.buildTree(charFreqs);

        // print out results
        System.out.println("SYMBOL\tWEIGHT\tHUFFMAN CODE");
        newCode.printCodes(tree, new StringBuffer());
    }

}

why did the guy used Stringbuffer

Because building a string using one is the preferred over string of concatenation.

StringBuilder vs String concatenation in toString() in Java

When to use StringBuilder in Java

etc...

StringBuilder is somewhat different than StringBuffer

Why use StringBuilder? StringBuffer can work with multiple thread as well as one thread?

and comparable

Because a priority queue is used. It needs that interface.

How do I use a PriorityQueue?

And, reading the Huffman coding Wikipedia page (which you can do to understand the algorithm), it is mentions that the optimal structure of the encoding is ordered. I don't know the algorithm, personally, but I will recommend not copying code off of the internet you don't understand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM