原文链接:https://blog.csdn.net/qq_29519041/article/details/81428934

哈夫曼树的建立
(1)初始化:根据给定的n个权值,构造n棵二叉树的森林集合F={T1,T2,…,Tn},其中每棵二叉树只有一个权值为Wi的根节点,左右子树均为空。
(2)找最小的树并构造新的树:在森林集合F中选取两颗根的权值最小的树作为左右子树构造一棵新的二叉树,新二叉树的根结点为新增加的结点,其权值为左右子树根的权值之和。
(3)删除与插入:在森林集合中删除已选取的两棵根的权值最小的树,同时将新构造的二叉树加入到森林集合F中。
(4)重复(2)和(3)步骤:直到森林集合只含有一棵树为止,这棵树即为哈夫曼树。

哈夫曼树(最优二叉树)

百度百科:https://baike.baidu.com/item/%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91/2305769?fr=aladdin

一. 目的:

找出存放一串字符所需的最少的二进制编码

二. 构造方法:

首先统计出每种字符出现的频率!(也可以是概率)//权值

------------------------------------------------------------------------------------------------

例如:频率表 A:60,    B:45,   C:13   D:69   E:14   F:5  G:3

第一步:找出字符中最小的两个,小的在左边,大的在右边,组成二叉树。在频率表中删除此次找到的两个数,并加入此次最小两个数的频率和。

F和G最小,因此如图,从字符串频率计数中删除F与G,并返回G与F的和 8给频率表

 重复第一步:

-------------------------------------------------------------------------------------------------

频率表 A:60,    B:45,   C:13   D:69   E:14   FG:8

最小的是 FG:8C:13,因此如图,并返回FGC的和:21给频率表。

---------------------------------------------------------------------------------------------------

重复第一步:

---------------------------------------------------------------------------------------------------

频率表 A:60    B: 45   D: 69   E: 14   FGC: 21

如图

-----------------------------------------------------------------------------------------------------

重复第一步

-----------------------------------------------------------------------------------------------------

频率表 A:60    B: 45   D: 69  FGCE: 35

-----------------------------------------------------------------------------------------------------

重复第一步

-----------------------------------------------------------------------------------------------------

频率表 A:60   D: 69  FGCEB: 80

-----------------------------------------------------------------------------------------------------

重复第一步

-----------------------------------------------------------------------------------------------------

频率表 AD:129  FGCEB: 80

添加 0 和 1,规则左0 右1

频率表 A:60,    B:45,   C:13   D:69   E:14   F:5  G:3

每个 字符 的 二进制编码 为(从根节点 数到对应的叶子节点,路径上的值拼接起来就是叶子节点字母的应该的编码)

字符 编码
A 10
B 01
C 0011
D 11
E 000
F 00101
G 00100

那么当我想传送 ABC时,编码为 10 01 0011

思考:

大家观察 出现得越多的字母,他的编码越短 ,出现频率越少的字母,他的编码越长。

在信息传输过程中,如果这个字母越多,那么我们希望他越瘦小(编码短)这样占用的编码越少,其实编码长的字母也是让频率比它多的字母把编码短的位子都占用后,他才去占用当前最短的编码。至此让总的编码长度最短。

且要保证长编码的不与短编码的字母冲突:

比如 不能出现 读码 读到 01  还有长编码的 字母为011,如果短编码为一个长编码的左起子串,这就是冲突,意思就是说读到当前位置已经能确定是什么字母时不能因为再读取一位或几位让这个编码能表示另外的字母,

但哈夫曼树(最优二叉树)在构造的时候就避免了这个问题。为什么能避免呢,因为哈夫曼树的它的字母都在叶子节点上,因此不会出现一个字母的编码为另一个字母编码左起子串的情况。

提问:

1.为什么要保证长编码不与短编码冲突?

冲突情况:如果我们已经确定D,E,F,G 用 01 ,010 ,10,001的2进制编码来传输了。那么想传送FED时,我需要传送     1001001,接收方可以把它解析为FDG(10 01 001),当然也能解析为FED(10 010 01),他两编码一样的,这就是编码冲突,(这里编码冲突的原因,也是因为编码时,D的编码是E的编码的左起子串了)显然这是不行的,就像我说压脉带,你如果是日本人会理解为 (你懂得),这就是发出同一种语,得出不同的意的情况。所以不能让一个字母的二进制代表数,为另一个字母的二进制代表数的子串。但为什么实际情况只要求编码时,一个编码不是另一编码的左起子串呢而不是绝对意义上的非子串呢,因为计算机从数字串的左边开始读,如果从右边读,那么可以要求是非右起(无奈)。你又可以问了为什么编码要求是非左起非右起不直接规定不能是子串呢(也行,不过=>),比如说原文中B就是C,F,G的子串,那这不就不符合规则了么。这里是为了哈夫曼的根本目的,优化编码位占用问题,如果完全不能有任何子串那么编码将会非常庞大。但这里计算机是一位一位的·读取编码的,只需要保证计算机在读取中不会误判就行。并且编码占用最少。

code:0110101001110

左起子串:011

右起子串:110

绝对非子串:1110111  此串在code中完全找不到

2.那么哈夫曼树怎么避免左起子串问题呢?

因为哈夫曼是从叶子节点开始构造,构造到根节点的,而且构造时,都是计算两个权值的节点的和与其他叶子节点再生成一个父节点来组成一个新的树。并且不允许任何带有权值的节点作为他们的父节点。这也保证了所有带有权值的节点都被构造为了叶子节点。然后最后编码的时候是从根节点开始走到叶子节点而得出的编码。在有权值的节点又不会出现在任何一条路的路途中的情况,只会出现在终点的情况下,因此不会出现01代表一个字母011又代表一个字母。

又如原文ABC编码为10010011的情况,当计算机读到10时,由于有左起子串不冲突的原则。那么计算机完全可以保证当前的10就是A字母,然后再往下读010011的部分,然后当读到01时,也完全能确定B,C同理,而不用说因为会出现冲突的编码而接着继续读取之后的编码来确定前面的编码。这样对信息的判断和效率是相当的不利的,也不是说不可以。即使你ABCD,分别用01,011,0111,01111来代替也行,传输后也能精确识别,但是数据量极大呢,想代替整个中文编码呢,那0后面得多少个1才能代表完。因此哈夫曼就是为了获得最少编码量代替最多字符串,并且不冲突,系统不会误判而产生的。

3.这里要提一下同权不同构

已经有朋友问起这个问题了。这里要说一下哈夫曼树的构造并不是唯一的

考虑如下情况:

有权值分别为 5,29,7,8,14,23,3,11的情况,可以如下图一样构造。

带权路径长度:

(5+3+7+8)*4+

(11+14)*3+

(23+29)*2

=271

也可以如下图构造:

带权路径长度:

(3+5)*5+

7*4+

(8+11+14)*3+

(23+29)*2

=271

这两种不同的方式构造出来的哈夫曼树,得出的带权路径长度相等,那么选哪颗树都可以,这就叫同权不同构

此问题由博主 https://me.csdn.net/weixin_43690959 昵称:叫我Tim就好了~ 提出,在这里对他表示感谢。

看懂的朋友留个赞,没看懂的留言我给你单独讲 _(:з」∠)_

哈夫曼树原理及构造方法相关推荐

  1. 哈夫曼树原理及其构造方法

    哈夫曼树 哈夫曼树 构造方法 哈夫曼树 构造方法 1.首先统计出每种字符出现的频率(概率)或权值 eg:(字符:权重) A:60 B:45 C:13 D:69 E:14 F:5 G:3 2.找出字符中 ...

  2. 哈夫曼树原理及Java编码实现

    文章目录 前言 一.哈夫曼树原理 二.哈夫曼编码(Java题解) 参考资料 前言 所有博客文件目录索引:博客目录索引(持续更新) 源代码:Gitee-Huffman.java.Github-Huffm ...

  3. 哈夫曼树原理,及构造方法

    哈夫曼树(最优二叉树) 百度百科:https://baike.baidu.com/item/%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91/2305769?fr=aladdi ...

  4. 哈夫曼树原理、画法和具体例子

    好久没画过哈夫曼树了,一做题发现全忘了..特别记录一下,以一道题的详细解答过程为例. 1.哈夫曼压缩原理 当各种指令出现的频度不均等时,对出现频度最高的指令用最短的位数表示,出现频度较低的则用较长的位 ...

  5. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  6. 数据结构---哈夫曼树

    数据结构-哈夫曼树 原理:参考趣学数据结构 代码: #include<stdio.h> #include<stdlib.h> #define N 100 #define INF ...

  7. 5.5.3哈夫曼树和哈夫曼编码

    太棒了小哥哥讲的 (ʃƪ ˘ ³˘)哈哈哈棒棒哒 大家好,本节后我们一起来学习,二产数应用的最后一个考点就是哈弗曼数,毕竟在哈佛迈出之前,我们先来了解一个知识点,就是什么是带全路径长度,我们之前学习过 ...

  8. 超好理解的哈夫曼树(最优二叉树)与例题

    对于比较官方的说法就是给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值 ...

  9. 最优二叉树(哈夫曼树)Java实现

    此篇博客讲最优二叉树也叫哈夫曼树的原理,以及构建步骤,还有哈夫曼编码原理.建议有二叉树基础朋友学习交流.对二叉树基础可以看我的另外一篇博客二叉树的构建以及遍历 文章目录 哈夫曼树引出: 哈夫曼树原理及 ...

最新文章

  1. 太牛了!30 年开源老兵,10 年躬耕 OpenStack,开源 1000 万行核心代码!
  2. 数字图像处理:第二十章 视频编码与压缩
  3. Java里的线程控制
  4. 嵌入式小白到大神学习全攻略(学习路线+课程+学习书籍+练习项目)
  5. HDU-4255 A Famous Grid BFS
  6. java 防止证书导出_如何把安全证书导入到java中的cacerts证书库
  7. JMETER Debug Sampler
  8. linux服务器启用光口,Ubuntu中启用ssh服务
  9. 安装navicat之后双击就会闪退_win2012,2016 能安装oracle 10g吗?
  10. cad没有命令输入框_cad中怎么输入文字?cad怎么输入文字?
  11. .net创建XML文件的两种方法
  12. SQL笔试经典50题
  13. BiLSTM-CRF模型理解
  14. python识别车辆图片_opencv+python车辆识别
  15. android切图的公式,APP的切图原理
  16. P2184 贪婪大陆 (线段树+差分思维)
  17. 机器学习/深度学习中的常用损失函数公式、原理与代码实践(持续更新ing...)
  18. Windows10数字权利
  19. 用户登录如何给密码加密xxtea.js
  20. 告别坚果云,使用nextcloud搭建私人同步云盘

热门文章

  1. TencentOS-tiny+ESP8266+mqttclient对接腾讯云平台IoThub
  2. Linux手工创建新用户
  3. 【豆瓣达人总结】做爱做的事,看有趣的人
  4. 使用spring注解注入bean
  5. 第4章_Java仿微信全栈高性能后台+移动客户端
  6. 实锤,PBlaze5实力演绎multiple namespaces 功能(下)
  7. doc2unix的安装及使用
  8. 谈谈智能手机软件(2):Linux手机软件
  9. linux 内核态 cos函数,浅析μCOS/II v2.85内核OSMboxPend()和OSMboxPost()函数工作原理
  10. 基于 UDP 的 组播、广播详解