哈夫曼树构造过程及最优证明
哈夫曼树
一、定义
哈夫曼树,又称最优树,是一类带权路径长度最短的树。首先有几个概念需要清楚:
1、路径和路径长度
从树中一个结点到另一个结点之间的分支构成两个结点的路径,路径上的分支数目叫做路径长度。树的路径长度是从树根到每一个结点的路径长度之和。
2、带权路径长度
结点的带权路径长度为从该结点到树根之间的路径长度与结点上权的乘积。树的带权路径长度为树中所有叶子结点的带权路径长度之和,通常记作WPL。
若有n个权值为w1,w2,…,wn的结点构成一棵有n个叶子结点的二叉树,则树的带权路径最小的二叉树叫做哈夫曼树或最优二叉树。
在上图中,3棵二叉树都有4个叶子结点a、b、c、d,分别带权7、5、2、4,则它们的带权路径长度为
(a)WPL = 7x2 + 5x2 + 2x2 + 4x2 = 36
(b)WPL = 4x2 + 7x3 + 5x3 + 2x1 = 46
(c)WPL = 7x1 + 5x2 + 2x3 + 4x3 = 35
其中(c)的WPL最小,可以验证,(c)恰为哈夫曼树。
二、哈夫曼树的创建与最优性证明
1.创建
假设有n个结点,n个结点的权值分别为w1<=w2,…,<=wn,构成的二叉树的集合为F={T1,T2,…,Tn},则可构造一棵含有n个叶子结点的哈夫曼树。步骤如下:
(1)从F中选取两棵根结点权值最小的树作为左右子树构造一棵新的二叉树,其新的二叉树的权值为其左右子树根结点权值之和;
(2)从F中删除上一步选取的两棵二叉树,将新构造的树放到F中;
(3)重复(1)(2),直到F只含一棵树为止。
2.最优性证明
条件:有TnT_nTn为带权w1≤w2≤...≤wn(n≥2)w_1\leq w_2\leq ... \leq w_n(n\geq 2)w1≤w2≤...≤wn(n≥2)的最优树。
试证明:
Q1:带权w1、w2w_1、w_2w1、w2的树叶Vw1、Vw2V_{w_1}、V_{w_2}Vw1、Vw2是兄弟,以树叶Vw1、Vw2V_{w_1}、V_{w_2}Vw1、Vw2为孩子的分支点,其通路长度最长。
Q2:最优树的收缩与展开形成的树仍为最优树。
Q5:两颗最优树合并仍为最优树。
Q4:哈夫曼树是最优树。
(1)证明:设通路长度最长的的分支点为VLmaxV_{L_{max}}VLmax,则VLmaxV_{L_{max}}VLmax一定有两个叶子节点。
因为VLmaxV_{L_{max}}VLmax是通路长度最长的的分支点,则其子节点必为叶子节点。假设VLmaxV_{L_{max}}VLmax只有一个叶子节点,VxV_xVx,则可以用子节点VwxV_{w_x}Vwx代替分支节点VLmaxV_{L_{max}}VLmax得到新树Tn∗T_{n}^*Tn∗,则有:
W(Tn∗)=W(Tn)−wxW(T_{n}^*) = W(T_n) - w_xW(Tn∗)=W(Tn)−wx 推出W(Tn∗)<W(Tn)W(T_{n}^*) < W(T_n)W(Tn∗)<W(Tn),与有TnT_nTn为最优树相矛盾。
(2)证明:VLmaxV_{L_{max}}VLmax的两个叶子节点的一定为Vw1、Vw2V_{w_1}、V_{w_2}Vw1、Vw2。
假设VLmaxV_{L_{max}}VLmax节点的两个子节点Vwx、VwyV_{w_x}、V_{w_y}Vwx、Vwy不是Vw1V_{w_1}Vw1(w1<wx,wyw_1<{w_x,w_y}w1<wx,wy),则将Vwx与Vw1V_{w_x}与V_{w_1}Vwx与Vw1互换得到新树Tn∗T_{n}^*Tn∗,令两棵树除去Vwx与Vw1V_{w_x}与V_{w_1}Vwx与Vw1节点,剩余部分带权路径长度为W(Tn−x−1)W(T_{n-x-1})W(Tn−x−1),则有:
W(Tn)=W(Tn−x−1)+(Lmax+1)∗wx+L1∗w1W(T_n) =W(T_{n-x-1}) + (L_{max} + 1)*w_x + L_1 * w_1W(Tn)=W(Tn−x−1)+(Lmax+1)∗wx+L1∗w1W(Tn∗)=W(Tn−x−1)+(Lmax+1)∗w1+L1∗wxW(T_n^*) =W(T_{n-x-1}) + (L_{max} + 1)*w_1 + L_1 * w_xW(Tn∗)=W(Tn−x−1)+(Lmax+1)∗w1+L1∗wx两式相减得:W(Tn)−W(Tn∗)=(wx−w1)∗(Lmax−L1+1)>0W(T_n)-W(T_n^*) = (w_x-w_1)*(L_{max}-L_1+1)>0W(Tn)−W(Tn∗)=(wx−w1)∗(Lmax−L1+1)>0与条件TnT_nTn为最优树冲突。故有:VLmaxV_{L_{max}}VLmax的一个叶子节点必为Vw1V_{w_1}Vw1。在此条件下,同理可证Vw2V_{w_2}Vw2是其另一个子节点。
综合(1)(2),Q1得证。
(3)证明:将Vw1、Vw2V_{w_1}、V_{w_2}Vw1、Vw2两个叶子节点收缩得到新树Tn−1∗(wLmax=w1+w2)T_{n-1}^*(w_{L_{max} } = w_1+w_2)Tn−1∗(wLmax=w1+w2),令带权为{w3、w4....wn、w1+w2w_3、w_4....w_n、w_1+w_2w3、w4....wn、w1+w2}的最优树为Tn−1T_{n-1}Tn−1,反向展开得到的树为Tn∗T_n^*Tn∗。则有:W(Tn)=W(Tn−1∗)+(w1+w2)W(T_n)=W(T_{n-1}^*)+(w_1+w_2)W(Tn)=W(Tn−1∗)+(w1+w2)W(Tn−1)=W(Tn∗)−(w1+w2)W(T_{n-1})=W(T_n^*)-(w_1+w_2)W(Tn−1)=W(Tn∗)−(w1+w2)整理得:W(Tn)−W(Tn∗)+W(Tn−1)−W(Tn−1∗)=0W(T_n)-W(T_{n}^*)+W(T_{n-1})-W(T_{n-1}^*)=0W(Tn)−W(Tn∗)+W(Tn−1)−W(Tn−1∗)=0因为Tn、Tn−1T_n、T_{n-1}Tn、Tn−1是最优树,当且仅当W(Tn)=W(Tn−1∗)且W(Tn−1)=W(Tn−1∗)W(T_n) = W(T_{n-1}^*)且W(T_{n-1}) = W(T_{n-1}^*)W(Tn)=W(Tn−1∗)且W(Tn−1)=W(Tn−1∗)时等式成立。即Tn∗、Tn−1∗T_n^*、T_{n-1}^*Tn∗、Tn−1∗也是最优树。
目前有结论:最优树从最远分支点的两个子叶支点收缩,得到的新树认为最优树。最优树可以继续收缩,依次类推直到节点数为1,按照收缩反向展开仍成立(其他展开方式不一定成立)。
(4)证明:两棵最优树合并仍为最优树。
将两棵树分别收缩至一个节点,再次收缩至一共一个节点,然后各自按照收缩方向反向展开,得到合并的树仍为最优树。
(5)哈夫曼树的创建过程就是最优树的合并过程,所以为最优树。
哈夫曼树构造过程及最优证明相关推荐
- 哈夫曼树构造算法的正确性证明
哈夫曼树构造 1.哈夫曼树的定义 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree). 2.哈夫曼树的构造 假 ...
- 最小堆实现哈夫曼树构造
0. 序 本以为用最小堆实现个哈夫曼树是个简单的事情,结果一不小心就花了好几个小时才写完...实现过程中主要有三个方面的问题没注意,导致花了很多时间进行调试. 一是多重指针malloc分配时要多加注意 ...
- 哈夫曼树构造以及代码实现
哈夫曼树构造以及代码实现 什么是哈夫曼树 理解哈夫曼树 哈夫曼树的构造 哈夫曼树构造-代码实现 什么是哈夫曼树 构造一颗二叉树,该树的带权路径长度达到最小,称为最优二叉树,也称为哈夫曼树(Huffma ...
- 哈夫曼树构造哈夫曼编码
在传输文字时,经常要将文字转换成二进制字符串.所以我们希望编码最短,但是又想保证它的唯一性.哈夫曼树具有最小带权路径长度,用来实现编码就可以编码最短,所以用哈夫曼树来构造编码.而前缀编码就可以保证在解 ...
- 算法学习笔记10——应用哈夫曼树构造最短的不等长编码方案
内容: (1)设需要编码的字符集为{d1, d2, -, dn},它们出现的频率为{w1, w2, -, wn},应用哈夫曼树构造最短的不等长编码方案. 提示: 哈夫曼树(Huffman Tree), ...
- 【Lua】哈夫曼树构造算法的分析与实现
哈夫曼树构造算法分析 1.哈夫曼树中权重越大的叶子离根越近,采用贪心算法构造哈夫曼树,首先选中权重值小的叶子结点进行构造 2.步骤 构造森林全是根:根据n个给定结点的权重值{W1, W2-Wn}构成 ...
- c语言哈夫曼树构造代码
c语言哈夫曼树构造代码 博主就很掘的一个人,最近学哈夫曼树,想着用指针去实现,觉得用指针实现,内存消耗会更少,写到后面发现越来与麻烦,且内存开销并没有减少,于是还是使用结构体数组中规中矩的去实现哈夫曼 ...
- 哈夫曼树构造原理及方法
哈夫曼树(最优二叉树) 百度百科:https://baike.baidu.com/item/%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91/2305769?fr=aladdi ...
- 关于哈夫曼树构造的结果探讨
哈夫曼树的构造算法想必我们大家都是耳熟能详的,对于大多数的题目都可以轻松构造出来,但是,我们也知道哈夫曼树的构造有的简单,有的较难,存在多种情况. 我们首先看哈夫曼树的构造方法描述 (1).根据 n ...
最新文章
- egg extend ts_KPL官方给各战队排T次:大王DYG,AG是老2、TS仅K
- Guid和Int还有Double、Date的ToString方法的常见格式
- 内网渗透测试:隐藏通讯隧道技术(下)
- Android“应用克隆”漏洞分析
- 查看安卓APK源码破解
- Verilog HDL语言设计实现过程赋值+译码器
- linux中命令对c文件进行编译,Linux下C语言编译基础及makefile的编写
- 遇到一个valgrind自身的bug
- Leecode刷题热题HOT100(12)——整数转罗马数字
- 个性化商品搜索相关研究梳理
- 刚刚!老干妈发布警方通报:3人伪造印章与腾讯签协议已刑拘,腾讯:辣椒酱不香了...
- 基于STM32的智能小车--避障设计
- 微星MS16j9鼠标面板可以移动指针,无法通过面板点击
- 实战HttpClient 接口调用以及获取token 设置请求头
- Cron表达式详解和表达式的验证
- Object Detection Meets Knowledge Graphs
- 【c#视频】——面向对象——多态
- R安装包失败解决办法
- 北京发布《政务服务领域区块链应用创新蓝皮书》| 附下载
- MySQL创建联合索引,字段的先后顺序,对查询的影响分析
热门文章
- MySQL 部署MHA集群部署
- 移动物联网卡管理系统有哪几张类型
- android 显示电池电量
- C++ assert
- 使用Mathtype的“插入下一章”导致整个自动生成的目录出现难看的章节号
- su oracle 什么意思,synonym.是什么意思
- oracle 12c sql图形化,Oracle 12c 查看CDBPDBs信息(SQL*PLUS)
- 非线性有限元:基本理论与算法及基于Python、Fortran程序实现
- 玩转内接多边形(一):任意多边形内均存在内接正三角形
- Alibaba开源UI框架V-Layout