赫夫曼编码
- 赫夫曼编码也翻译为 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式, 属于一种程序算法。
- 赫夫曼编码是赫哈夫曼树在电讯通信中的经典的应用之一。
- 赫夫曼编码广泛地用于数据文件压缩。其压缩率通常在 20%~90%之间。
- 赫夫曼码是可变字长编码(VLC)的一种。Huffman 于 1952 年提出一种编码方法,称之为最佳编码。
定长编码:把直接字符翻译成对应的Ascli编码。然后再把Ascli编码直接翻译成2进制。
变长编码:比如统计各字符出现的次数,根据次数进行编码,出现次数越多的,编码越小。
前缀编码:指每个字符的编码都不能是其他字符的前缀,这就保证了编码的可读性,不会发生一对多的现象。
赫夫曼编码的思路:
赫夫曼编码是一种前缀编码。它的思路是,首先统计要传递的各字符的数量,然后根据数量创建赫夫曼树,然后根据赫夫曼树,给每一个字符编码,比如指定向左是0向右是1,根据每个字符的路径为它编码。这样,由于赫夫曼树的特点,出现次数多的字符排在上面,这就保证了它的编码较小,而每个字符都会排在叶子节点,这就保证了编码不会有重复前缀。
代码
将一句英文句子转为赫夫曼编码主要分为几步:
- 将字符串转化为bytes数组。
- 统计各字符的出现次数。使用map,循环bytes数组,数字作为key,出现的次数为value。
- 将得到的map转化为list,这样便于创建赫夫曼树。需要创建好树节点,然后遍历map,把数据放到树节点里,再把树节点放到list里。
- 创建赫夫曼树。根据赫夫曼树的规则创建树,新建的根节点值为null,最后返回树的根节点。
- 根据树的路径,得到编码的map。左0右1,根据StringBuilder拼接路径,寻找叶子节点。
- 根据编码表map,先获得编码字符串,再将字符串按照8个1位转为bytes数组。
package hufffmanTree;
import java.util.*;
/**
* 赫夫曼编码压缩
*/
public class HuffmanCodeDemo {
static Map<Byte,String> codeMap=new HashMap<>();
static StringBuilder stringBuilder=new StringBuilder();
public static void main(String[] args) {
//原字符串
String str="i like like like java do you like a java";
//转化成byte用来传输
byte[] bytes=str.getBytes();
System.out.println(Arrays.toString(bytes));
//得到赫夫曼编码结果
byte[] code = huffmanCode(bytes);
System.out.println(Arrays.toString(code));
}
//封装方法
public static byte[] huffmanCode(byte[] bytes){
//获得了各字符的出现次数
Map<Byte, Integer> map =