哈夫曼树&哈夫曼编码
引入
哈夫曼、赫夫曼、霍夫曼都说的是——Huffman
哈夫曼树和哈夫曼编码到底解决啥问题呢?
先看两个常经常用来解释的例子:
1. 对学生成绩进行评级
本部分(例子1)出自博客# 树问题总结之哈夫曼树
下面就是在一次考试中某门课程的各分数段的人数分布情况:
下面我们就利用哈夫曼树寻找一棵最佳判定树,即总的比较次数最少的判定树。
第一种构造方式:
第二种构造方式:
这两种方式,显然后者的判定过程的效率要比前者高。在也没有别地判定过程比第二种方式的效率更高。
2. 哈夫曼编码
具体可以搜百度,或者看这个博客——哈夫曼编码的理解(Huffman Coding)
就是把字符用不等长的形式给都编码了。
哈夫曼树做了一件什么事情?
由例子我们可以总结出:哈夫曼树就是一种算法思路,它能够使得,当只能用判断(是或否,也就是if条件语句)的形式,从一堆元素中快速的找到所要的元素。换句话说哈夫曼树就是一种提高判断搜索能力的算法。
回顾上面两个例子:
第一个例子中,我们需要快速判断出所需要的分的类是什么,可以通过哈夫曼树去做
第二个例子中,我们需要最少的判断,就把字符给确定了。
什么问题适合用哈夫曼树解决?
除了刚刚说的,它是用来从一堆元素中查找元素的算法,当你需要用最少的判断步骤获取最重要的那个元素的时候,就用哈夫曼树,那么它有一些很重要的前提:
-
查找过程中只用判断结构
-
这堆元素必须可排序
- 例如二分查找就是一个例子,从有1~100个数的顺序数组中找到输入的数n,怎么找呢?可以先对100个数进行哈夫曼树的构建,在构建过程中你会发现每个数的权重都是1啊没办法排序,这时候可以根据数的大小来排序,但是构建哈夫曼树的时候依然用权重来构建,最后,构建出来的每个非叶子结点中表示的判断,就是二分查找。
- 再比如刚刚的两个例子中,排序过程是通过每个结点中自带的权重来排序的,因此它产生的效果就是能够最快的
仔细研究哈夫曼树的构建步骤会发现至关重要的问题:
1.怎么去选择两个子结点去结合成一个父结点?——元素要有结合的规则,比如权重小的两个结合
2.当结点和结点的结合规则相同的时候怎么办(例如很多结点当权重相同的时候,谁和谁结合呢)?——元素排列的顺序也要有规则也就是1~100这一百个数权重相同的的时候咋办呢?虽然说很多人的做法就是当结点和结点权重相同的时候,就随机取两个数结合成一个,这样是不便于判断语句的分类的,如果判断语句变得很臃肿,蕴含很多小判断,这样就会加重程序负担。因此就给它加了个权重相同时的排序,按照元素大小排序,这个可以简化判断语句。