哈夫曼编码应用实例
哈夫曼编码,主要用途是实现数据压缩。
设给出一段报文:CAST CAST SAT AT A TASA。字符集合是 { C, A, S, T },各个字符出现的频度(次数)是 W={ 2, 7, 4, 5 }。若给每个字符以等长编码A : 00 T : 10 C : 01 S : 11,则总编码长度为 ( 2+7+4+5 ) * 2 = 36。
若按各个字符出现的概率不同而给予不等长编码,可望减少总编码长度。各字符出现概率为{ 2/18, 7/18, 4/18, 5/18 },化整为 { 2, 7, 4, 5 }。以它们为各叶结点上的权值, 建立霍夫曼树。左分支赋 0,右分支赋 1,得霍夫曼编码(变长编码)。A : 0 T : 10 C : 110 S : 111。它的总编码长度:7*1+5*2+( 2+4 )*3 = 35。比等长编码的情形要短。霍夫曼编码是一种无前缀编码。解码时不会混淆。带权路径长度达到最小的二叉树即为霍夫曼树。在霍夫曼树中,权值大的结点离根最近。
霍夫曼算法
1.由给定的 n 个权值 {w0, w1, w2, …, wn-1},构造具有 n 棵扩充二叉树的森林 F = { T0, T1, T2, …, Tn-1 },其中每棵扩充二叉树 TI 只有一 个带权值 wi 的根结点, 其左、右子树均为空。
2.重复以下步骤, 直到 F 中仅剩下一棵树为止:
① 在 F 中选取两棵根结点的权值最小的扩充二叉树,做为左、右子树构造一棵新的二叉树。置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。
② 在 F 中删去这两棵二叉树。
③ 把新的二叉树加入 F。
#include 《stdio.h》
#include 《stdlib.h》
#include 《string.h》
#define MAX 32767
typedef char *HuffmanCode;
typedef struct
{
int Weight;//字母的权
int Parent,Leftchild,Rightchild;
}HuffmanTree;