编码方式:
1)定长码:每个不同字符的编码长度是规定的,译码是唯一的。
2)变长码:每个不同字符的编码长度不同,比定长码方案好,但译码困难。
前缀码:
1)定义:对任一字符的一个0,1串编码,都不是其他字符编码的前缀
2)作用:前缀性质可以使译码方法非常简单
3)表示:用完全二叉树来表示,即树中任一结点都有2个儿子结点
平均码长:其中C表示字符集,c表示任意字符,f(c)表示字符出现的频率,也即权值,dT(c)表示前缀码长。
最优前缀码:使平均码长达到最小的前缀码编码方案称为给定编码字符集C。
1、构造哈夫曼树
1)根据给定的n个权值 ,构造n棵只有一个根结点的二叉树, n个权值分别是这些二叉树根结点的权。设F是由这n棵二叉树构成的集合;
2)在F中选取两棵根结点树值最小的树作为左、右子树,构造一颗新的二叉树,置新二叉树根的权值=左、右子树根结点权值之和;
3)从F中删除这两颗树,并将新树加入F;
4)重复步骤 2、3,直到F中只含一颗树为止。
贪心策略:每次选择权值最小的子树构造新的二叉树。
2、哈夫曼算法
/*定义树的结构体*/
private static class Huffman implements Comparable{
Bintree tree;
static float weight;
private Huffman(Bintree tt,float ww){
tree=tt;
weight=ww; //权重
}
public int comoareTo(Object x){
float xw=((Huffman)x).weight;
if(weight<xw)
return -1;
if(weight==xw)
return 0;
}
}
/*构造哈夫曼树的算法,其中f[]为字符权值数组*/
private static Bintree huffmanTree(float[]f){
//生成只有根结点的单结点树
int n=f.length;
Huffman[]w=new Huffman [n+1]; //定义二叉树的结构
Bintree zero=new Bintree(); //构造空子树
for(int i=0;i<n;i++){
Bintree x=new Bintree();
x.makeTree(new MyInteger(i),zero,zero); //左右孩子均为空
w[n+1]=new Huffman(x,f[i]); // 刻画根结点的权值
}
MinHeap H=new MinHeap(); // 创建极小堆
H.initialize(w,n); //堆初始化
/*反复合并最小权值的子树*/
for(int i=0;i<n;i++){
Huffman x-(Huffman)H.removeMin(); //取出堆顶元素,即最小元素x,并调整堆
Huffman y-(Huffman)H.removeMin(); //继续取出堆顶元素,即次小元素y,并调整堆
Bintree z=new Bintree(); //定义根结点
z.makeTree(null,x.tree,y.tree); //构造具有左右孩子 x,y 的子树 z
Huffman t=new huffman(z,x,weight+y,weight); //计算父结点z的权值
H.put(t); //将根的权值插入堆
}
return ((Huffman)H.removeMin()).tree; //返回生成树,即哈夫曼树
}
复杂度分析:初始化极小堆时需计算时间O(n),其函数remove() 和put() 运算时间需O(logn),总共n-1次合并需要时间O(nlogn),故哈夫曼算法的时间复杂度为 T(n)=O(nlogn)
3、贪心选择性质
已知 c 是字符集,f(x)≤f(c) , f(y)≤f(c),且
证明:存在 T'',使得( x 与 y 的码长相等),且 x 与 y 为兄弟(权值最小),当 x,y 在任何位置时,需要证明 B(T'') ≤ B(T') ≤ B(T)。如下图:
所以 B(T') ≤ B(T),同理可证B(T'') ≤ B(T') ==> B(T'') ≤ B(T') ≤ B(T) ==> B(T'') ≤ B(T),由假设B(T) ≤ B(T'') ==> B(T) = B(T'')
4、最优子结构性质
已知T'为最优,x,y 为叶结点且同为兄弟,z为其父亲,则f(z) = f(x) + f(y),T = T'- {x,y} U {z}
证明:T'= T- {x,y} 为c’ = c - {x,y} U {z},所以T' 表示字符集c’ 的一个最优前缀码,需证明 B(T)=B(T')+f(x)+f(y) 且T' 是c’ 的最优
②反证:假设T'不是最优,而T''是最优,则
B(T''') = B(T'')+f(x)+f(y) ≤ B(T')+f(x)+f(y) = B(T),即B(T''') ≤ B(T),得证T'''为最优,与假设T'' 最优矛盾。如下图: