package com.interview.books.question300; import com.interview.leetcode.utils.TreeNode; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.PriorityQueue; /** * Created_By: stefanie * Date: 14-12-17 * Time: 上午10:35 */ public class TQ38_HuffmanEncode { public class HuffmanTreeNode extends TreeNode { char ch; public HuffmanTreeNode(char ch, int val) { super(val); this.ch = ch; } } public static Comparator<HuffmanTreeNode> comparator = new Comparator<HuffmanTreeNode>() { @Override public int compare(HuffmanTreeNode o1, HuffmanTreeNode o2) { if(o1.val == o2.val){ return o1.ch - o2.ch; } else { return o1.val - o2.val; } } }; public HashMap<Character, String> encode(HashMap<Character, Integer> frequency){ PriorityQueue<HuffmanTreeNode> heap = new PriorityQueue<>(frequency.size(), comparator); for(Map.Entry<Character, Integer> ch : frequency.entrySet()){ heap.add(new HuffmanTreeNode(ch.getKey(), ch.getValue())); } while(heap.size() > 1){ HuffmanTreeNode first = heap.poll(); HuffmanTreeNode second = heap.poll(); HuffmanTreeNode parent = new HuffmanTreeNode('#', first.val + second.val); parent.left = first; parent.right = second; heap.add(parent); } HashMap<Character, String> encodes = new HashMap<>(); encode(heap.poll(), "", encodes); return encodes; } private void encode(HuffmanTreeNode node, String prefix, HashMap<Character, String> encodes){ if(node == null) return; if(node.left == null && node.right == null){ encodes.put(node.ch, prefix); } else { encode(((HuffmanTreeNode) node.left), prefix + "0", encodes); encode(((HuffmanTreeNode)node.right), prefix + "1", encodes); } } public static void main(String[] args){ TQ38_HuffmanEncode encoder = new TQ38_HuffmanEncode(); HashMap<Character, Integer> frequency = new HashMap<>(); frequency.put('a', 2); //110 frequency.put('b', 5); //0 frequency.put('c', 3); //111 frequency.put('d', 4); //10 HashMap<Character, String> encode = encoder.encode(frequency); for(Map.Entry<Character, String> ch : encode.entrySet()){ System.out.println(ch.getKey() + ": " + ch.getValue()); } } }