哈夫曼树以及哈夫曼编码

本文介绍了哈夫曼树的概念,它是具有最小带权路径长度的二叉树,适用于数据压缩。哈夫曼编码是一种变长编码,遵循频率高字符编码短的规则,并确保编码无前缀冲突。通过构建哈夫曼树,可以得到最优的前缀编码,从而达到数据传输效率最大化。尽管编码不唯一,但哈夫曼树确保了带权路径长度最小,实现编码长度最短。
摘要由CSDN通过智能技术生成

1.哈夫曼树
假设有n个权值{w1, w2, …, wn},试构造一棵含有n个叶子结点的二叉树,每个叶子节点带权威wi,则其中带权路径长度WPL最小的二叉树叫做最优二叉树或者哈夫曼树。
特点:哈夫曼树中没有度为1的结点,故由n0 = n2+1以及m= n0+n1+n2,n1=0可推出m=2*n0-1,即一棵有n个叶子节点的哈夫曼树共有2n-1个节点

2.哈夫曼编码
通信传送的目标是使总码长尽可能的短。
变长编码的原则:
1.使用频率高的字符用尽可能短的编码(这样可以减少数据传输量);
2.任一字符的编码都不能作为另一个字符编码的开始部分(这样就使得在两个字符的编码之间不需要添加分隔符号)。这种编码称为前缀编码。
根据每种字符在电文中出现的次数构造哈夫曼树,将哈夫曼树中每个分支结点的左分支标上0,右分支标上1,把从根结点到每个叶子结点的路径上的标号连接起来,作为叶结点所代表的字符的编码。这样得到的编码称为哈夫曼编码。
思考:为什么哈夫曼编码符合变长编码的原则?哈夫曼树所构造出的编码的长度是不是最短的?
哈夫曼树求得编码为最优前缀码的原因: 在构造哈夫曼树的过程中:
1.权值大的在上层,权值小的在下层。满足出现频率高的码长短。
2.树中没有一片叶子是另一叶子的祖先,每片叶子对应的编码就不可能是其它叶子编码的前缀。即上述编码是二进制的前缀码。
假设每种字符在电文中出现的次数为wi (出现频率即为权值),其码长为li,电文中只有n种字符,则编码后电文总码长为,而哈夫曼树是WPL(树的带权路径长度)最小的二叉树,因此哈夫曼编码的码长最小。
注意:哈夫曼编码是不唯一的,这与构造哈夫曼树过程相关,但是哈夫曼树WPL是固定的。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 8   //Huffman树叶结点数 
#define M 2*N-1  //Huffman树结点个数 
#define MAX 1000

/*构造Huffman树和Huffman编码 */
//Huffman树和Huffman编码的存储表示
typedef struct
{
    unsigned int weight;    
    unsigned int parent, lchild, rchild;
}HTNode,HuffmanTree[M+1];     //HuffmanTree[M+1]存储Huffman树结点 

typedef char* HuffmanCode[N+1];  // HuffmanCode[N+1]存储Huffman编码字符串指针 


//找出数组中无父节点且权值最小的两个节点下标存储于s1,s2且权值s1<&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值