哈夫曼树及其应用

哈夫曼树

哈夫曼树的基本概念

结点间的路径:从一个结点到另一个结点之间的分支序列。
结点间的路径长度:从一个结点到另一个结点之间的所经过的分支数目。
例如:B到F?
路径:BE、EF 路径长度:2
在这里插入图片描述
结点的权:给结点赋予的具有某种意义的实数,该实数称为结点的权。
结点的带权路径长度:把从树根到某一结点的路径长度与该结点权的乘积,称为该结点的带权路径长度。
例如:结点F的带权路径长度?
7×3=21
树的路径长度PL:树中从根到各个结点的路径长度之和。
树的带权路径长度WPL :树中从根到叶子结点的各个带权路径长度之和。
例如:
PL=0+1+1+2+2+3+3=12
WPL=4×2+7×3+5×3+2×1
=46
问题1:什么样的二叉树的路径长度最小?
完全二叉树的路径长度最小,但不唯一。
PLa=0+1+1+2+2=6
PLb=0+1+1+2+2=6
在这里插入图片描述
在这里插入图片描述
问题2:什么样的带权路径长度最小?
WPLa=7×2+5×2+2×2+4×2=36
WPLb=4×2+7×3+5×3+2×1=46
WPLc=7×1+5×2+2×3+4×3=35
在这里插入图片描述
在叶子数目及权值相同的二叉树中,完全二叉树不一定是最优二叉树。
一般情况下,最优二叉树中,权值越大的叶子离根越近;权值越小的叶子离根越远。

构造哈夫曼树

(1) 哈夫曼树的概念
哈夫曼树:是由n个带权叶子结点构成的二叉树中带权路径最短的二叉树,又称又称最优二叉树。
哈夫曼树的形态不唯一。
(2) 构造哈夫曼树的算法步骤
① 初始化:用给定的n个权值{w1,w2,…wn}构造n棵二叉树并购成森林F={T1,T2,…,Tn},其中每棵二叉树都是单结点二叉树。
② 找最小树:在森林F中选出两个根结点的权值最小的二叉树合并,作为一棵新二叉树的左、右子树,标记新二叉树的根结点权值为其左、右子树根结点权值之和。
③ 删除与加入:从森林F中删除选取的那两棵二叉树,并将新二叉树加入森林F中;
④ 判断:重复②、③步,直到森林F中只含有一棵二叉树为止,此时得到的二叉树就是哈夫曼树。
例1:给定一组权值{7,4,3,2},构造哈夫曼树
在这里插入图片描述
例2:给定一组权值{3,8,7,2,5},构造哈夫曼树
在这里插入图片描述

哈夫曼树的类型定义

(1) 存储结构
哈夫曼树是最优二叉树,可以用通用链式存储结构。
哈夫曼树有n个叶子结点,n-1度为2的结点,结点总数2n-1个。
哈夫曼树的顺序存储结构:一维结构数组,构成静态三叉链表。
静态三叉链表的结点结构:权值、双亲序号、左孩子序号、右孩子序号。
在这里插入图片描述
哈夫曼树的顺序存储结构:
在这里插入图片描述
(2) 哈夫曼树类型的定义

#define N 20  /* 叶子结点的最大值 */
#define M 2*N-1  /* 结点的最大值*/
typedef struct {
	int Weight;  /* 结点的权值 */
	int Parent;  /* 双亲的下标 */
	int LChild;  /* 左孩子的下标 */
	int RChild;  /* 右孩子的下标 */
} HTNode,HuffmanTree[M+1];

创建哈夫曼树:初始化 + 选择、删除合并

在这里插入图片描述

哈夫曼编码

哈夫曼树的概念

二进制编码:用二进制序列表示字符。
定长编码:每个字符用相同数目的二进制位编码。
ASCII编码:一个英文字符用7位二进制位编码,使用一个字节,最高位规定为0。
例如:A 0100 0001
a 0110 0001
前缀编码:任一字符的编码都不是其它字符编码的前缀。
例如:编码系统01、001、010、100、110就不是前缀编码。
01001:01、001
01001:010、01
哈夫曼编码:对一棵具有n个叶子结点的哈夫曼树,若对树中的每个左分支赋0,右分支赋1(也可以规定左1右0),则从根到每个叶子路径上的二进制串就是哈夫曼编码。
哈夫曼编码的性质:
(1) 哈夫曼编码是前缀编码
(2) 哈夫曼编码是最优前缀编码
例:要传送数据state, seat, act, tea, cat, set, a, eat, 请给出各字符的哈夫曼编码。
在这里插入图片描述

cat编码为:0101011
在这里插入图片描述
在这里插入图片描述
例:设有一台模型机,共有7种不同的指令,其使用频率如下表所示,请设计哈夫曼编码。
在这里插入图片描述
哈夫曼编码的平均码长=
=0.40×1+0.30×2+0.15×3+0.05×5
+0.04×5+0.03×5+0.03×5
=2.20
显然,2.20<3
例:计算1000条指令定长编码总位数和哈夫曼编码总位数。
1000×3=3000
1000×2.20=2200
欢迎大家加我微信交流讨论(请备注csdn上添加)
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
数据结构算法分析》实验报告 姓名 学号_ _____ __年 __月__ __日 上机题目:以静态链表为存储结构,编写给定权值{7,19,2,6,32,3}构造哈夫曼树算法。 (输出以存储结构表示或以树型显示(90度旋转)) 需求分析 1. 输入数据必须为int的整形数据,其数值范围为:-~47 2. 输出的数据格式为:%d 3. 测试数据的数据为:{7,19,2,6,32,3} 详细设计 1. 该程序采用顺序表的存储结构,其数据结构定义如下: #define n 6 #define m 2*n-1 #define max 100typedef struct {int data; int lchild,rchild,prnt; }hufmtree; 所用数据类型中每个操作的伪码算法如下: 创建哈夫曼树 Program hufm(hufmtree t[m]) FOR i=0;i<m;i++ TO t[i].data=0; t[i].lchild=0; t[i].rchild=0; t[i].prnt=0; End FOR 输入结点值 FOR i=n;i<m;i++ TO p1=0;p2=0; small1=max;small2=max FOR j=0;j<=i-1;j++ TO IFt[j].prnt?=0 IF(t[j].data<small1) small2=small1; small1=t[j].data; p2=p1; p1=j;} ELSE IF(t[j].data<small2) small2=t[j].data; p2=j; t[p1].prnt=i+1; t[p2].prnt=i+1; t[i].lchild=p1+1; t[i].rchild=p2+1; t[i].data=t[p1].data+t[p2].data; END IF END FOR END Hufman 调试分析 1. 调试过程中主要遇到哪些问题?是如何解决的? 开始的时候main函数的数据结构类型定义的与主函数不同,而且缺少返回值,导致最 后的结果陷入死循环,通过看书,向同学询问,得以解决。 2. 经验和体会 哈夫曼树又称最优二叉树,此次实验创建哈夫曼树算法,虽然依旧犯了不少错误,但 仍解决了。在其中学习了很多,对树有了更深的了解。 测试结果 附件 见 058詹奇.Cpp ----------------------- 数据结构算法分析实验报告全文共3页,当前为第1页。 数据结构算法分析实验报告全文共3页,当前为第2页。 数据结构算法分析实验报告全文共3页,当前为第3页。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程子的小段

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值