哈夫曼树Huffman Tree及其应用——哈夫曼编码

本文介绍了哈夫曼树的概念、构造方法及其在哈夫曼编码中的应用。通过权值最小的叶子节点靠近根节点的原则,构建最小带权路径长度的二叉树。此外,还讨论了哈夫曼编码的无二义性以及如何通过哈夫曼树构造编码,以节省存储空间。最后,提到了与其他类型的树如二叉搜索树、平衡二叉树的对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

构造这种树的算法最早由哈夫曼于1952年提出的,因此称之为哈夫曼树。

什么是哈夫曼树(Huffman Tree)+概念
(1)带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带 有权值 wk,从根结点到每个叶子结点的长度为 Lk,则每个叶子结 点的带权路径长度之和就是:WPL=w1L1+w2L2+…+wn*Ln。 最优二叉树或哈夫曼树: WPL最小的二叉树
(2)结点的权:在许多的应用中,将树中的结点赋予一个有着实际意义的数值,称此数值为该结点的权。
(3)结点的带权路径长度:从根结点到某个结点的路径长度与该结点所带的权值的乘积为该结点的带权路径长度。

构造一棵哈夫曼树
根据哈夫曼树的定义,一棵二叉树要使其WPL值最小,必须使权值越大的叶子节点越靠近根节点,而权值越小的叶子节点越远离根节点。那么如何构造一棵哈夫曼树呢?其方法如下:
(1)给定的n个权值{W1,W2,…,Wn}构造n棵只有一个叶子节点的二叉树,从而得到一个二叉树的集合F={T1,T2,…,Tn};
(2)在F中选取根节点的权值最小和次小的两棵二叉树作为左、右子树构造一棵新的二叉树,这棵新的二叉树根节点的权值为其左、右子树根节点权值之和;
(3)在集合F中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到集合F中;
(4)重复(2)、(3)两步,当F中只剩下一棵二叉树时,这棵二叉树便是所要建立的哈夫曼树。
注:每次把权值最小的两棵二叉树合并

*做题试试:*W={ 0.05, 0.29, 0.07, 0.08, 0.14, 0.23,0.03, 0.11}
在这里插入图片描述
构造一棵哈夫曼树的算法
其算法思路是:
1.n个叶子结点只有data和weight域值,先将所有2n-1个结点的parent、lchild和rchild域置为初值0。
2.处理每个非叶子结点ht[i](存放在ht[n+1]~ht[2n-1]中):从ht[1] ~ht[i-1]中找出根结点(即其parent域为0)最小的两个结点ht[lnode]和ht[rnode],将它们作为ht[i]的左右子树,ht[lnode]和ht[rnode]的双亲结点置为ht[i],并且ht[i].weight= ht[lnode].weight+ht[rnode].weight。
3.如此这样直到所有n-1个非叶子结点处理完毕。
用ht[]数组存放哈夫曼树,对于具有n个叶子结点的哈夫曼树,总共有2n-1个结点。

typedef struct  /*哈夫曼树结点的结构*/
{
   
char data;        /*数据用字符表示*/
int weight;       /*权值*/
int parent;       /*双亲*/
int leftchild;     /*左孩子*/
int rightchild;   /*右孩子*/
}HuffNode;

int HuffmanCreate(HuffNode *ht)
{
      
int i,k,n,min1,min2,lnode,rnode;
printf("请输入元素个数:");
scanf("%d",&n);
for(i=1;i<=n;i++)            
/* 输入结点值和信息 */
{
       
getchar()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值