一、哈夫曼树的概念和定义

什么是哈夫曼树?

让我们先举一个例子。

判定树:

        在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设计直接影响着程序的执行效率。例如,编制一个程序,将百分制转换成五个等级输出。大家可能认为这个程序很简单,并且很快就可以用下列形式编写出来:
 
[cpp] view plain copy print?
  1. if(score<60)
  2. cout<<"Bad"<<endl;
  3. else if(score<70)
  4. cout<<"Pass"<<endl
  5. else if(score<80)
  6. cout<<"General"<<endl;
  7. else if(score<90)
  8. cout<<"Good"<<endl;
  9. else
  10. cout<<"Very good!"<<endl;
  if(score<60)cout<<"Bad"<<endl;else if(score<70)cout<<"Pass"<<endlelse if(score<80)cout<<"General"<<endl;else if(score<90)cout<<"Good"<<endl;elsecout<<"Very good!"<<endl;

 

若考虑上述程序所耗费的时间,就会发现该程序的缺陷。在实际中,学生成绩在五个等级上的分布是不均匀的。当学生百分制成绩的录入量很大时,上述判定过程需要反复调用,此时程序的执行效率将成为一个严重问题。
 

但在实际应用中,往往各个分数段的分布并不是均匀的。下面就是在一次考试中某门课程的各分数段的分布情况: 

下面我们就利用哈夫曼树寻找一棵最佳判定树,即总的比较次数最少的判定树。
 
 
第一种构造方式:
 
第二种构造方式:
这两种方式,显然后者的判定过程的效率要比前者高。在也没有别地判定过程比第二种方式的效率更高。
我们称判定过程最优的二叉树为哈夫曼树,又称最优二叉树
 
===================================================================================================
 

定义哈夫曼树之前先说明几个与哈夫曼树有关的概念:

路径: 树中一个结点到另一个结点之间的分支构成这两个结点之间的路径。

路径长度:路径上的分枝数目称作路径长度。

树的路径长度:从树根到每一个结点的路径长度之和。

结点的带权路径长度:在一棵树中,如果其结点上附带有一个权值,通常把该结点的路径长度与该结点上的权值

                                                              之积称为该结点的带权路径长度(weighted path length)

  什么是权值?( From 百度百科 )

     计算机领域中(数据结构)

  权值就是定义的路径上面的值。可以这样理解为节点间的距离。通常指字符对应的二进制编码出现的概率。

  至于霍夫曼树中的权值可以理解为:权值大表明出现概率大!

  一个结点的权值实际上就是这个结点子树在整个树中所占的比例.

  abcd四个叶子结点的权值为7,5,2,4. 这个7,5,2,4是根据实际情况得到的,比如说从一段文本中统计出abcd四个字母出现的次数分别为7,5,2,4. 说a结点的权值为7,意思是说a结点在系统中占有7这个份量.实际上也可以化为百分比来表示,但反而麻烦,实际上是一样的.

树的带权路径长度:如果树中每个叶子上都带有一个权值,则把树中所有叶子的带权路径长度之和称为树的带

                                   权路径长度。

             设某二叉树有n个带权值的叶子结点,则该二叉树的带权路径长度记为:

                                  

公式中,Wk为第k个叶子结点的权值;Lk为该结点的路径长度。

示例:

======================================================================================================
一般来说,用n(n>0)个带权值的叶子来构造二叉树,限定二叉树中除了这n个叶子外只能出现度为2的结点。
那么符合这样条件的二叉树往往可构造出许多颗,
其中带权路径长度最小的二叉树就称为哈夫曼树或最优二叉树
 
===============================================================================
 

  二、哈夫曼树的构造

 
根据哈弗曼树的定义,一棵二叉树要使其WPL值最小,必须使权值越大的叶子结点越靠近根结点,而权值越小的叶子结点
越远离根结点。
 
哈弗曼依据这一特点提出了一种构造最优二叉树的方法,其基本思想如下:
下面演示了用Huffman算法构造一棵Huffman树的过程:

三、哈夫曼树的在编码中的应用

在电文传输中,需要将电文中出现的每个字符进行二进制编码。在设计编码时需要遵守两个原则:
(1)发送方传输的二进制编码,到接收方解码后必须具有唯一性,即解码结果与发送方发送的电文完全一样;
(2)发送的二进制编码尽可能地短。下面我们介绍两种编码的方式。
 
1. 等长编码
            这种编码方式的特点是每个字符的编码长度相同(编码长度就是每个编码所含的二进制位数)。假设字符集只含有4个字符A,B,C,D,用二进制两位表示的编码分别为00,01,10,11。若现在有一段电文为:ABACCDA,则应发送二进制序列:00010010101100,总长度为14位。当接收方接收到这段电文后,将按两位一段进行译码。这种编码的特点是译码简单且具有唯一性,但编码长度并不是最短的。
 
2. 不等长编码
            在传送电文时,为了使其二进制位数尽可能地少,可以将每个字符的编码设计为不等长的,使用频度较高的字符分配一个相对比较短的编码,使用频度较低的字符分配一个比较长的编码。例如,可以为A,B,C,D四个字符分别分配0,00,1,01,并可将上述电文用二进制序列:000011010发送,其长度只有9个二进制位,但随之带来了一个问题,接收方接到这段电文后无法进行译码,因为无法断定前面4个0是4个A,1个B、2个A,还是2个B,即译码不唯一,因此这种编码方法不可使用。
 
因此,为了设计长短不等的编码,以便减少电文的总长,还必须考虑编码的唯一性,即在建立不等长编码时必须使任何一个字符的编码都不是另一个字符的前缀,这宗编码称为前缀编码(prefix  code)
 
 
 
(1)利用字符集中每个字符的使用频率作为权值构造一个哈夫曼树;
(2)从根结点开始,为到每个叶子结点路径上的左分支赋予0,右分支赋予1,并从根到叶子方向形成该叶子结点的编码
 
 
例题:
假设一个文本文件TFile中只包含7个字符{A,B,C,D,E,F,G},这7个字符在文本中出现的次数为{5,24,7,17,34,5,13}
利用哈夫曼树可以为文件TFile构造出符合前缀编码要求的不等长编码
 
具体做法:
 
1. 将TFile中7个字符都作为叶子结点,每个字符出现次数作为该叶子结点的权值
2. 规定哈夫曼树中所有左分支表示字符0,所有右分支表示字符1,将依次从根结点到每个叶子结点所经过的分支的二进制位的序列作为该
     结点对应的字符编码
3. 由于从根结点到任何一个叶子结点都不可能经过其他叶子,这种编码一定是前缀编码,哈夫曼树的带权路径长度正好是文件TFile编码
    的总长度
 
通过哈夫曼树来构造的编码称为哈弗曼编码(huffman code)
 

 
 转载地址:http://blog.csdn.net/shuangde800/article/details/7341289

霍夫曼树和霍夫曼编码原理相关推荐

  1. python哈夫曼树_python霍夫曼树

    class Node(): data=0 left=None right=None father=None def __init__(self,data,left,right): self.data= ...

  2. 霍夫曼树(赫夫曼树、哈夫曼树)

    霍夫曼树:给定n个权值做为n个叶子节点,若该树的带权路径长度达到最小,这棵树为最优二叉树,也称赫夫曼树. 霍夫曼树中的几个概念 路径和路径长度 一棵树中,一个节点往下可以达到的孩子或孙子节点之间的通路 ...

  3. 哈夫曼树(霍夫曼树)-详解

    哈夫曼树(霍夫曼树)-详解 哈夫曼树(霍夫曼树)-详解 何为权值?我们看下百度百科的解释. 何为路径? 何为路径长度? 何为树的路径长度? 何为结点的带权路径长度? 何为树的带权路径长度(WPL)? ...

  4. 创建霍夫曼树,霍夫曼编码以及使用霍夫曼编码压缩文件

    那么,什么是霍夫曼树(赫夫曼树)呢? 给定n个权值(权值就是每个节点里面存放的数据,但是根据业务需求不同,存放的数据类型有些差别)作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样 ...

  5. 霍夫曼树及霍夫曼编码的C语言实现,霍夫曼树及霍夫曼编码的C语言实现

    从周五开始学习霍夫曼树,一直到今天终于完成,期间遇到了各类各样的棘手的问题,经过一遍遍在纸上分析每一步的具体状态得以解决.如今对学习霍夫曼树的过程加以记录web 首先介绍霍夫曼树数组 霍夫曼树(Huf ...

  6. Huffman霍夫曼树,霍夫曼编码

    霍夫曼树基本概念: 路径:从一个结点往下到孩子或孙子结点之间的同理 路径长度:如结点1到结点7的路径长度=2 结点的权:将结点的某一属性值作为结点的权 带权路径长度:从根节点到该结点*该结点的权:如结 ...

  7. 霍夫曼树与霍夫曼编码

    霍夫曼树以及哈夫曼编码 一.什么是哈夫曼树与哈夫曼编码 编码是什么 答: 在ASCII 编码中 'a' = 97 = ( 01100001 ) 2 (01100001)_2 (01100001)2​ ...

  8. 霍夫曼树和霍夫曼编码以及霍夫曼编码的应用

    文章目录 霍夫曼树介绍 1.1霍夫曼树的定义 1.2霍夫曼树的几个概念 1.3构建霍夫曼树的过程 1.4代码实现霍夫曼树 霍夫曼编码介绍 什么是霍夫曼编码 通信领域的应用 字符串压缩 1.构造霍夫曼树 ...

  9. 霍夫曼树以及霍夫曼编码(动态数组实现方式)

    霍夫曼编码是用于数据压缩存储的.根据的原理是:任一个字符编码绝对不是另一个字符编码的前缀,并且出现次数最多的字符,所用编码的位数最小.以此来达到数据压缩的目的. 霍夫曼树有两种实现方式:一种是基于链表 ...

  10. 一文看懂哈夫曼树与哈夫曼编码

    转自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299884.html 在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUF ...

最新文章

  1. ElasticSearch性能优化策略【转】
  2. Apache ServiceComb Pack 微服务分布式数据最终一致性解决方案
  3. 海量数据随机抽样问题(蓄水池问题)
  4. java 简单类继承
  5. vim配置python开发环境_GitHub - TTWShell/legolas-vim: Vim配置,为python、go开发者打造的IDE。...
  6. 产品设计:APP个人信息保护指引
  7. JAVA类与对象(一)----基础概念理解
  8. linux 加密文件,如何运用OpenSSL 对文件进行加密和解密
  9. android定位坑简书,android webview 定位问题
  10. 打标工具labelme或者labelimg遇到图片闪退的完美解决方案
  11. 手机连接adb操作步骤
  12. 大二狗卸任社团职位以及对专业发展方向的思考与总结
  13. IDEA 2018.3.6 修改背景图片
  14. NLM6XX系列无线无源采发仪的工作模式
  15. charles对iOS手机的https进行抓包(图文教程)
  16. 微信小程序连接mysql
  17. 拆分单元格快速复制内容
  18. 牛客-判断一个链表是否为回文结构
  19. 关于.9图失效以及.9图不可以错过的细节点
  20. Windows7 Ubuntu 双系统安装卸载工具备份

热门文章

  1. Bzoj2959: 长跑
  2. 高通MSM8255 GPS 调试分析Android系统之Broadcom GPS 移植【转】
  3. 泊松分布(一种离散分布)
  4. 计算机网络信息安全毕业设计题目,网络信息安全系统毕业设计
  5. 【愚公系列】2022年10月 微信小程序-电商项目-商品详情页面的标题及价格功能实现
  6. 推荐3个计算机专业的英文电子书下载网站
  7. 程序员常用 英语单词
  8. openstack项目中遇到的各种问题总结 其二(云主机迁移、ceph及扩展分区)
  9. 同源、跨域、跨站、SameSite与withCredentials
  10. C# wpf ScrollBar自定义音量调节样式滚动条