1. 程式人生 > >java使用優先級隊列實現哈夫曼編碼

java使用優先級隊列實現哈夫曼編碼

哈夫曼編碼 左右 integer string enc ash 小根堆 rac sta

思路:
  1. 構建小根堆
  2. 根據小根堆實現哈夫曼樹
  3. 根據哈夫曼樹對數據進行編碼
代碼實現如下:
/**
 * @Author: DaleyZou
 * @Description: 使用java實現一個哈夫曼編碼的小程序
 * @Date: Created in 19:45 2018-9-27
 * @Modified By:
 */
public class HuffmanCode {
    private class Node implements Comparable<Node>{
        char ch; // 字符
        int freq; // 權值
        boolean isLeaf;  // 是否是葉子節點
        Node left, right;  // 父節點的左節點和右節點

        // 初始化一個帶權值的葉子節點
        public Node(char ch, int freq){
            this.ch = ch;
            this.freq = freq;
            this.isLeaf = true;
        }

        // 構建一個節點,帶左右節點
        public Node(Node left, Node right, int freq){
            this.left = left;
            this.right = right;
            this.freq = freq;
            this.isLeaf = false;
        }

        @Override
        public int compareTo(Node node) {
            return this.freq - node.freq;
        }
    }

    // 構建一顆哈夫曼樹
    public Map<Character, String> encode(Map<Character, Integer> frequencyForChar){
        PriorityQueue<Node> priorityQueue = new PriorityQueue<>();
        for (Character ch : frequencyForChar.keySet()){
            priorityQueue.add(new Node(ch,frequencyForChar.get(ch)));
        }
        while (priorityQueue.size() != 1){ // 構建小根堆
            Node left = priorityQueue.poll();
            Node right = priorityQueue.poll();
            priorityQueue.add(new Node(left, right, left.freq + right.freq));
        }
        return encode(priorityQueue.poll());
    }

    public Map<Character, String> encode(Node root){
        HashMap<Character, String> hashMap = new HashMap<>();
        encode(root, "", hashMap);
        return hashMap;
    }

    public void encode(Node root, String encoding, HashMap<Character,String> hashMap) {
        if (root.isLeaf){ // 已經到葉子節點,遞歸結束
            hashMap.put(root.ch, encoding);
            return;
        }
        encode(root.left, encoding + "0" ,hashMap);     // 編碼左節點
        encode(root.right, encoding + "1", hashMap);    // 編碼右節點
    }

    // 測試結果是否正確
    public static void main(String[] args){
        Map<Character, Integer> frequencyForChar = new HashMap<>();
        frequencyForChar.put(‘a‘, 10);
        frequencyForChar.put(‘b‘, 20);
        frequencyForChar.put(‘c‘, 40);
        frequencyForChar.put(‘d‘, 80);

        HuffmanCode huffmanCode = new HuffmanCode();
        Map<Character, String> encode = huffmanCode.encode(frequencyForChar);
        for (Character ch : encode.keySet()){
            System.out.println(ch + " : " + encode.get(ch));
        }
    }

}

不使用優先級隊列,自己手動實現小根堆

java使用優先級隊列實現哈夫曼編碼