哈夫曼樹(Huffman Tree),又稱最優二叉樹,是帶權路徑長度(WPL)最小的二叉樹。它廣泛應用於數據壓縮(如 ZIP、JPEG)、加密編碼等領域。
以字符串 aaaaaaaaaabbbbbaaaaaccccccccddddddfff 為例:
最終得到的哈夫曼樹所有原始字符均位於葉子節點,WPL 最小。
package huffman;
public class Node {
public String code; // 哈夫曼編碼
public int codeSize; // 編碼長度
public String data; // 字符數據
public int count; // 權值
public Node lChild, rChild;
public Node() {}
public Node(String data, int count) { this.data = data; this.count = count; }
public Node(int count, Node l, Node r) { this.count = count; this.lChild = l; this.rChild = r; }
public Node(String data, int count, Node l, Node r) { this.data = data; this.count = count; this.lChild = l; this.rChild = r; }
}
package huffman;
import java.util.*;
public class Huffman {
private String str;
private String newStr = "";
private Node root;
private ArrayList<String> charList;
private ArrayList<Node> nodeList;
public void creatHfmTree(String str) {
this.str = str;
charList = new ArrayList<>();
nodeList = new ArrayList<>();
// 1. 統計字符頻率
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
boolean flag = true;
for (int j = 0; j < charList.size(); j++) {
if (charList.get(j).charAt(0) == ch) {
charList.set(j, charList.get(j) + ch);
flag = false;
break;
}
}
if (flag) charList.add(ch + "");
}
// 2. 創建節點
for (int i = 0; i < charList.size(); i++) {
String data = charList.get(i).charAt(0) + "";
int count = charList.get(i).length();
nodeList.add(new Node(data, count));
}
// 3. 排序並合併
sort(nodeList);
while (nodeList.size() > 1) {
Node left = nodeList.remove(0);
Node right = nodeList.remove(0);
Node parent = new Node(left.count + right.count, left, right);
nodeList.add(0, parent);
sort(nodeList);
}
root = nodeList.get(0);
}
private void sort(ArrayList<Node> list) {
for (int i = 0; i < list.size() - 1; i++) {
for (int j = i + 1; j < list.size(); j++) {
if (list.get(i).count > list.get(j).count) {
Node t = list.get(i);
list.set(i, list.get(j));
list.set(j, t);
}
}
}
}
// 中序遍歷輸出權值
public void output(Node node) {
if (node.lChild != null) output(node.lChild);
System.out.print(node.count + " ");
if (node.rChild != null) output(node.rChild);
}
public static void main(String[] args) {
Huffman huff = new Huffman();
huff.creatHfmTree("sdfassvvdfgsfdfsdfs");
huff.output();
}
}
本文通過概念解析、圖解步驟、完整 Java 代碼,系統講解了哈夫曼樹的構建原理與實現。掌握該算法有助於理解數據壓縮核心邏輯,也是經典面試考點。