什么是哈夫曼树
哈夫曼树的定义
带权路径长度:设二叉树有n个叶子结点,每个叶子结点带有权值Wk,从根结点到每个叶子结点的长度为lk,则每个叶子结点的带权路径长度之和就是:
【例】有五个叶子结点,权值分别为[1,2,3,4,5],用此权值序列可以构造出不同的多个二叉树。
1、WPL = 5X1 + 4X2 + 3X3 + (1+2)X4 = 34
2、WPL = 1X1 + 2X2 + 3X3 + (5+4)X4 = 50
3、WPL = 3X2 + (4+5)X2 + (1+2)X3 = 33
哈夫曼树的构造
typedef struct TreeNode *HuffmanTree;
struct TreeNode{
int Weight;
HuffmanTree Left,Right;
};
HuffmanTree Huffman(MinHeap H){
int i;
HuffmanTree T;
BuildMinHeap(H);
for(i = 1; i < H->Size; i++){
T=malloc(sizeof(struct TreeNode));
T->Left = DeleteMin(H);
T->Right = DeleteMin(H);
T->Weight = T->Left->Weight+T->Right->Weight;
Insert(H,T);
}
T = DeleteMin(H);
return T;
}
哈夫曼树的特点
1、没有度为1的结点。
2、n个叶子结点的哈夫曼树共有2n-1个结点。
3、哈夫曼树的任意非叶结点的左右子树交换后仍是哈夫曼树。
4、对同一组权值,存在不同构的两棵哈夫曼树。
哈夫曼编码
给定一段字符串,如何对字符进行编码,使得该字符串的编码存储空间最小。
【例】假设有一段文本包含58个字符,并由以下7个字符字符构成:a,e,i,s,t,空格(sp),换行(nl),只是出现的次数不同。如何对这7个字符编码(只能用0和1表示一个字符)?
方法1:用等长ASCII码:(每个字符用8位表示)58X8=464位。
方法2:用等长3位编码:(3位数,每位选择0或1表示,能表示8种字符)58X3=174位。
方法3:出现频率高的字符编码短,出现频率低的字符编码长。
方法3要求避免编码二义性,可以用二叉树进行编码。
Q:为五个使用频率不同的字符设计哈夫曼编码,下列方案中哪个不可能是哈夫曼编码?
A.00,100,101,110,111
B.000,001,01,10,11
C.0000,0001,001,01,1
D.000,001,010,011,1
A:选A。画出A的图为:(图来自百度知道)
可以看出,a节点的度为1。哈夫曼树结点的度不能为1。所以不对。
Q:一段文本中包含对象{a,b,c,d,e},其出现次数相应为{3,2,4,2,1},则经过哈夫曼编码后,该文本所占总位数为:
A.12
B.27
C.36
D.其它都不是
A:选B。画图如下:
文本所占总位数=3X1+3X2+2X2+2X3+2X4=27