import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class HuffmanCodeDemo {
public static void main(String[] args) {
String str = "i like like like java do you like a java";
byte[] bytes = str.getBytes();
ArrayList nodes = getNodes(bytes);
Node root = createHuffmanTree(nodes);
StringBuilder builder = new StringBuilder();
getCodes(root, "", builder);
// System.out.println(huffmanCode);
for (Map.Entry<Byte, String> map : huffmanCode.entrySet()) {
System.out.printf("[%c, %s] ", (char)map.getKey().byteValue(), map.getValue());
}
}
public static ArrayList<Node> getNodes(byte[] bytes) {
ArrayList<Node> list = new ArrayList<>();
HashMap<Byte, Integer> counts = new HashMap<>();
int len = bytes.length;
for (int i = 0; i < len; i++) {
Integer count = counts.get(bytes[i]);
if (count == null) {
counts.put(bytes[i], 1);
} else {
counts.put(bytes[i], count + 1);
}
}
for (Map.Entry<Byte, Integer> entry : counts.entrySet()) {
list.add(new Node(entry.getKey(), entry.getValue()));
}
return list;
}
public static Node createHuffmanTree(ArrayList<Node> nodes) {
while (nodes.size() > 1) {
Collections.sort(nodes);
Node leftNode = nodes.get(0);
Node rightNode = nodes.get(1);
nodes.remove(leftNode);
nodes.remove(rightNode);
Node parent = new Node(null, leftNode.weight + rightNode.weight);
parent.left = leftNode;
parent.right = rightNode;
nodes.add(parent);
}
return nodes.get(0);
}
static HashMap<Byte, String> huffmanCode = new HashMap<>();
public static void getCodes(Node node, String code, StringBuilder builder) {
StringBuilder stringBuilder = new StringBuilder(builder);
if (node != null) {
stringBuilder.append(code);
if (node.data != null) {
huffmanCode.put(node.data, stringBuilder.toString());
}
getCodes(node.left, "0", stringBuilder);
getCodes(node.right, "1", stringBuilder);
}
}
}
class Node implements Comparable<Node> {
public Byte data;
public int weight;
public Node left;
public Node right;
public Node(Byte data, int weight) {
this.data = data;
this.weight = weight;
}
@Override
public String toString() {
return "[" + data + " ," + weight + "]";
}
@Override
public int compareTo(Node o) {
return this.weight - o.weight;
}
public void preOrder() {
System.out.print("=>" + this);
if (this.left != null) {
this.left.preOrder();
}
if (this.right != null) {
this.right.preOrder();
}
}
}
结果: