1. 程式人生 > >Java資料結構和演算法(四)赫夫曼樹

Java資料結構和演算法(四)赫夫曼樹

Java資料結構和演算法(四)赫夫曼樹

哈夫曼樹又稱為最優二叉樹,赫夫曼樹的一個最主要的應用就是哈夫曼編碼。

一、赫夫曼樹

can you can a can as a can canner can a can.

1.1 定長編碼

99 97 110 32 121 111 117 32 99 97 110 32 97 32 99 97 110 32 97 115 32 97 32 99 97 110 32 99 97 110 110 101 114 32 99 97 110 32 97 32 99 97 110 46

1100011 1100001 1101110 100000 1111001 1101111 1110101 100000 1100011 1100001 1101110 100000 1100001 100000 1100011 1100001 1101110 100000 1100001 1110011 100000 1100001 100000 1100011 1100001 1101110 100000 1100011 1100001 1101110 1101110 1100101 1110010 100000 1100011 1100001 1101110 100000 1100001 100000 1100011 1100001 1101110 

定長編碼長度:8 * 44 = 352

1.2 變長編碼

定長編碼雖然簡單,但實際上有的字元出現的頻率高有的低,可以將出現頻率高的編碼設定的短些,頻率低的設定的長些,這樣編碼後的長度也會減少。

// 每個字元出現的頻率
r:1 s:1 u:1 e:1 y:1 .:1 o:1 c:7 n:8  :11 a:11

0=a,1= ,10=n,11=c,100=o,101=.,110=y,111=e,1000=u,1001=s,1010=y
11 0 10 1 1010 100 1000 1 11 0 10 1 0 1 11 0 10 1 0 1001 1 0 1 11 0 10 1 11 0 10 10 111 null 1 11 0 10 1 0 1 11 0 10 101

採用上述編碼雖然減少了長度,但無法解碼。如 1 到底是 , n, c, o ... 無法確定。

字元的編碼都不能是其他字元編碼的字首,符合此要求的編碼叫做字首編碼。

1.3 赫夫曼編碼

java public static TreeNode<Integer> huffman(int[] arr) { List<TreeNode<Integer>> huffmanTree = new ArrayList<>(); for (int i : arr) { huffmanTree.add(new TreeNode(i)); } while (huffmanTree.size() > 1) { // 1. 排序 Collections.sort(huffmanTree, (TreeNode<Integer> o1, TreeNode<Integer> o2) -> { return o1.getValue() - o2.getValue(); }); // 2. 取出最小的 2 個數形成一個新的節點 TreeNode<Integer> left = huffmanTree.remove(0); TreeNode<Integer> right = huffmanTree.remove(0); TreeNode<Integer> head = new TreeNode(left.getValue() + right.getValue()); head.setLeft(left); head.setRight(right); huffmanTree.add(head); } return huffmanTree.get(0); }


每天用心記錄一點點。內容也許不重要,但習慣很重要!