哈夫曼树与哈夫曼编码

什么是哈夫曼树

带权路径长度:设二叉树有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

哈夫曼树的构造

构造过程即为在权值中找到两个最小的元素,求和后,删除他们,并将和最为新的元素。
这个过程若排序实现的话,每次计算都要重新排序找最小,比较繁琐,可以根据最小堆实现,
时间复杂度为N*logN。
这是最大堆的删除函数,最小堆与其相似。

MaxHeap DeleteMax(MaxHeap H)
{
    int Parent,Child;
    int Maxitem,temp;
    if(IsEmpty(H)){
        printf("最大堆已经为空");
        return;
    }
    Maxitem=H->element[1];//先把要删除的要素保存起来
    temp=H->element[H->size--];//找到最边界的元素存起来,因为删除了了个元素,size要再减去1.
    for(Parent=1;Parent*2<H->size;Parent=Child){//parent*2就是其左儿子,如果存在就可以进行循环。
        Child=Parent*2;
        if((Child!=H->size)&&(H->element[Child]<H->element[Child+1]))
            Child++;//如果右儿子大,就切换到右儿子
        if(temp>=H->element[Child])break;
        else//否则就与左儿子交换
            H->element[Parent]=H->element[Child];//循环目的就是找到其左右儿子中较大的那个
}
H->element[Parent]=temp;
return H;
}

建造哈夫曼树的代码:

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要求避免编码二义性,可以用二叉树进行编码。

为了避免二义性,首先要了解前缀码。任何一字符的编码都不是另一字符的前缀码,因此树形结构可以避免二义性的出现。
在这里插入图片描述

例题

在这里插入图片描述
根据边与结点数目的对应关系,并且哈夫曼树没有只有一个儿子的节点,列出等式求解。
在这里插入图片描述
根据0或者1尝试画出每棵树,发现A选项中存在含有一个儿子的节点。
在这里插入图片描述根据出现次数构造哈夫曼树,结果应为每个结点的高度与出现次数乘积的和。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值