一.简介
把信息转换成计算机能够识别的二进制形式,被称为编码。按编码位数长度是否固定分为:定长编码、变长编码。
定长编码容易设计,运行效率高。如果要对数据信息压缩就需要采用变长编码,把出现频率高的用位数少的编码,出现频率低的用更多位编码便可以实现数据压缩。
霍夫曼树是一种WPL(树的带权路径) 最小的二叉树,二叉树刚好有左/右节点,可以方便映射为2进制(如左节点方向表示0,右节点方向表示1)。
霍夫曼编码是一种可变长编码方式,依据字符出现频率作为霍夫曼树节点的权重构建霍夫曼树。
二.实现
package com.vincent;
import java.io.ByteArrayOutputStream;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
String msg = "I love coding,I love java too!";
Map<Byte,String> encodingTable = HuffmanTree.encodingTable(msg.getBytes());
System.out.println(encodingTable);
System.out.println(Arrays.toString(msg.getBytes()));
byte[] encodingBytes = HuffmanTree.encode(msg.getBytes(),encodingTable);
System.out.println(Arrays.toString(encodingBytes));
System.out.println(Arrays.toString(HuffmanTree.decode(encodingBytes,encodingTable)));
}
}
class HuffmanTree{
/**
* 霍夫曼树节点
* @param <T>
*/
private static class Node<T> implements Comparable<Node<T>>{
//存储的节点数据
private T item;
//节点权重
private int weight;
private Node<T> left;
private Node<T> right;
public Node(T item,int weight){
this.item = item;
this.weight = weight;
}
@