import java.util.ArrayList; public class HuffmanTree { private String str; private BinaryNodeInterface root; private ArrayList charList; private ArrayList freqList; public HuffmanTree(String aString) { str = aString; root = null; generateFrequencyList(); generateHuffmanTree(); } public BinaryNodeInterface getRootNode() { return root; } private void generateHuffmanTree() { if(str == null || str.equals("")) { root = null; return; } MinHeapInterface> heap = new MinHeap>(); while(!charList.isEmpty()) { char c = charList.remove(0); int freq = freqList.remove(0); BinaryNodeInterface newNode = new BinaryNode(c); BinaryNodeFrequency newBNode = new BinaryNodeFrequency(newNode, freq); heap.add(newBNode); } while(!heap.isEmpty()) { BinaryNodeFrequency left = heap.removeMin(); if(heap.isEmpty()) { root = left.node; break; } BinaryNodeFrequency right = heap.removeMin(); int newFrequency = left.frequency + right.frequency; BinaryNodeInterface newNode = new BinaryNode(null, (BinaryNode) left.node, (BinaryNode) right.node); BinaryNodeFrequency newBNode = new BinaryNodeFrequency(newNode, newFrequency); heap.add(newBNode); } if(root.isLeaf()) { BinaryNodeInterface newNode = new BinaryNode(null, (BinaryNode) root, null); root = newNode; } } private void generateFrequencyList() { charList = new ArrayList(); freqList = new ArrayList(); int strLength = str.length(); for(int i = 0; i < strLength; i++) { char c = str.charAt(i); int charIndex = charList.indexOf(c); if(charIndex != -1) { freqList.set(charIndex, freqList.get(charIndex) + 1); } else { charList.add(c); freqList.add(1); } } } /* The min heap requires the object to implement comparable. According * to the algorithm, we need to add BinaryNode into the min heap. However, * BinaryNodes are not comparable, so we need a new type of object that * can be used to represent a BinaryNode that implements Comparable. * In this situation, our BinaryNode will be used to store a character. * To compare, we compare the frequency of the character. */ private class BinaryNodeFrequency implements Comparable> { private BinaryNodeInterface node; private int frequency; private BinaryNodeFrequency(BinaryNodeInterface aNode, int aFrequency) { node = aNode; frequency = aFrequency; } public int compareTo(BinaryNodeFrequency otherBNF) { if(frequency < otherBNF.frequency) { return -1; } else if(frequency > otherBNF.frequency) { return 1; } else { return 0; } } } }