背景:一篇全英文文档(ASCII字符集最多出现128个字符),现在要实现哈夫曼编码压缩?
—中文采用UTF-8编码的话一样原理,不过可能堆的大小改变一下,每次堆都是出现频率最小的k个字符组成的即可
1.统计每个字符出现的次数;
a.字典树统计
b.哈希表统计
2.统计完成后放入一个数组中,数组是HuffmanTreeNode[] array类型的数组,
class HuffmanTreeNode{
char value;
int weight;
HuffmanTreeNode left;
HuffmanTreeNode right;
}
3.对数组进行BuidHeap成一个最小堆;
4.执行两次DeleteMin后,把取出来的min1和min2合并成一个树minN1(minN1的weight=min1.weight+min2.weight,left=min1,right=min2),再把minN1执行insert
进入堆中;
5.一直执行直到最后只剩下一个就是最优哈弗曼编码树(每次出两个进一个肯定会逐渐减少的);
6.遍历哈弗曼树得到每个字符及其对应的编码放入HashMap中即可;
—规定左路径为0,右路径为1即可得到每个字符的编码
—字符出现频率最小的肯定在树的最底层,编码最多
7.然后顺序遍历文件每个字符编码成HashMap中对应的编码即可形成一个二进制文件编码流;
如:adacaeda;
统计:a:4,d:2,c:1,e:1
先拿c和e合并:
2
c1 e1
然后和d合并:
4
2 d2
c1 e1
最后a即可:
8
4 a4
2 d2
c1 e1
可以看出编码:
a:1
d:01
c:000
e:001
一共需要的二进制位数是:2+4+8=14个bit即可全部表示adacaeda了,原本的ASCII编码需要8*8=64个bit才行;