节点类
class Node implements Comparable<Node> {
Byte data;
int weight;
Node left;
Node right;
public Node(Byte data, int weight) {
this.data = data;
this.weight = weight;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
", weight=" + weight +
'}';
}
@Override
public int compareTo(Node o) {
return this.weight - o.weight;
}
}
全局静态变量
static Map<Byte, String> huffmanCodesMap = new HashMap<>();
static StringBuilder stringBuilder = new StringBuilder();
static Integer lastDigitCapacity = null;
byte[] 封装Node集合
private static List<Node> getNodes(byte[] bytes) {
List<Node> nodes = new ArrayList<>();
Map<Byte, Integer> map = new HashMap<>();
for (byte b : bytes) {
Integer value = map.get(b);
map.put(b, value == null ? 1 : value + 1);
}
map.forEach((k, v) -> {
Node node = new Node(k, v);
nodes.add(node);
});
return nodes;
}
创建赫夫曼树
private static Node createHuffmanTree(List<Node> nodes) {
while (nodes.size() > 1) {
Collections.sort(nodes);
Node leftNode = nodes.get(0);
Node rightNode = nodes.get(1);
Node parentNode = new Node(null, leftNode.weight + rightNode.weight);
parentNode.left = leftNode;
parentNode.right = rightNode;
nodes.remove(leftNode);
nodes.remove(rightNode);
nodes.add(parentNode);
}
return nodes.get(0);
}
生成赫夫曼编码
private static void getCodes(Node root) {
if (root != null) {
getCodes(root, "", stringBuilder);
}
}
private static void getCodes(Node node, String code, StringBuilder stringBuilder) {
StringBuilder stringBuilder2 = new StringBuilder(stringBuilder);
stringBuilder2.append(code);
if (node != null) {
if (node.data == null) {
getCodes(node.left, "0", stringBuilder2);
getCodes(node.right, "1", stringBuilder2);
} else {
huffmanCodesMap.put(node.data, stringBuilder2.toString());
}
}
}
赫夫曼编码压缩
private static byte[] zip(byte[] bytes, Map<Byte, String> huffmanCodesMap) {
StringBuilder stringBuilder = new StringBuilder();
for (byte b : bytes) {
String code = huffmanCodesMap.get(b);
stringBuilder.append(code);
}
int len = 0;
if (stringBuilder.length() % 8 == 0) {
len = stringBuilder.length() / 8;
} else {
len = stringBuilder.length() / 8 + 1;
}
byte[] zipBytes = new byte[len];
int index = 0;
for (int i = 0; i < stringBuilder.length(); i += 8) {
String str;
if (i + 8 > stringBuilder.length()) {
str = stringBuilder.substring(i)