Lecture 13-1

绪论

Lecture 10介绍的是树状数据结构,内容包括了两种存储结构——孩子链存储结构,孩子兄弟链存储结构,以及两种遍历方式。

Lecture 11介绍了树中最为重要的一个分支二叉树以及将基于孩子兄弟链存储结构的树和森林转化成二叉树的方法。

Lecture 12介绍了一种重要的特殊二叉树——堆,以及基于完全二叉树的一种优化方案——“Complete Heap”。

"Complete Heap"的一种重要应用就是优先队列,Lecture 13介绍的就是基于优先队列实现的一种重要算法——Huffman coding。


The Basic Idea

哈夫曼编码其实我们已经学习过非常多的次数了,我个人一直认为系统学习任何算法的基础在于储备知识和充分了解算法所使用的确切环境还有该算法到底解决了什么问题。

那么第一个问题就是编码是什么?

百度百科的解释如下:

编码是信息从一种形式或格式转换为另一种形式的过程,也称为计算机编程语言的代码简称编码。用预先规定的方法将文字、数字或其它对象编成数码,或将信息、数据转换成规定的电脉冲信号。

简单来说,就是给一个类的每个单种对象指定一个计算机方便读写的01码。这样基于这个类的对象组成的信息都能够通过01码的方式进行表达和传送,同时传送过去的01码希望能够被转化回原本的信息,这个过程称为解码。

根据概念我们最容易想到的编码就是按照种类的次序进行自然二进制编码,例如英文字母表:

a——00000
b——00001
c——00010
······
x——10111
y——11000
z——11001

这确实是最简单的一种编码,但是最简单的往往不一定在任何情况下最好的。假设现在存在一种情形是文本的信息量非常大,需要你尽可能地减少使用的01个数,自然二进制编码在这种情况很有可能就不够好了。

接下来看下面这个例子:

假设只有三种对象a,b和c,给a的编码是0,给b的编码是1,给c的编码是01,这种编码显然不是自然二进制编码,那么这种编码可行么?

显然是不行的,如果远端传来的编码是01,那么这个编码对应的到底是ab还是c?这样的编码无法进行解码,也违反了编码的唯一性。

深究以下这种情况出现的原因,是存在一种对象的编码是另一种对象编码的前缀,这在导致第二种对象的使用时无法分别到底是第二种对象还是第一种对象和其他对象的组合(勉强来说某种情况下也能分辨)。

所以我们在指定编码时有时想要尽可能地避免上面的情况,完全避免上述情况的编码则称为前缀码。

哈夫曼编码就是对于某个文本保证01字符使用个数最少的前缀码编码方式。


Scan the text

基本思想那里对编码的介绍提到,编码的指定和实际文本的情况以及需求是息息相关的。哈夫曼编码是一种字符使用个数最少的前缀码的编码方式,需求现在已经确定了,编码方式和文本的实际情况是直接相关的。

例如,同样由a,b,c三个字母组成的两段文本信息:

aaaaaaaaaaaaaabbbbbbbbbbbccccc
ccccccccccccccccbbbbbbbbbbaaaaaa

可以很明显的发现两段文本中a,b,c三个字母出现的频率都不相同,且频率大小次序刚好相反,那么显然对于第一段文本的最优前缀码,在第二段文本中显然不是最优的。

scan是扫描的意思,在进行哈夫曼编码之前,我们需要扫描文本来确定每种对象出现的频率。

Lecture 13-1_第1张图片


Prioritize characters

根据几种对象出现的频率分配优先级,哈夫曼编码的基本算法思想是贪心法,直接想法是给出现频率相对高的对象分配短编码,出现频率相对低的对象分配长编码。

Lecture 13-1_第2张图片

Lecture 13-1_第3张图片


Building A Tree

前面都是算法运作的背景和想要解决的问题,建树则是算法运行的容器和主体。

建树的理论过程具体见这篇文章,伪流程如下:

每次将优先队列中出队两个频率最低的对象。
将两个对象建成一棵树,树的根结点是抽象出来的对象,频率为两个对象频率之和。
将抽象出来的对象进队。

Lecture 13-1_第4张图片

当优先队列中仅存在一个抽象结点时,这个抽象结点对应的树就是哈夫曼树,所有具体的结点都是这颗哈夫曼树的叶子节点,从根结点到叶子节点的路径就是该对象对应的编码,其中向左为0向右为1,得到编码的过程靠深度优先搜索。

Lecture 13-1_第5张图片

Lecture 13-1_第6张图片
因为都是具体的对象都是叶子节点,不存在一个叶子节点是另一个叶子结点的祖先,所以也不存在一个对象对应的编码是另一个对象对应的编码的前缀。


总结

没什么总结,哈夫曼编码的使用和代码设计都是非常简单的。但是如何将用贪心法设计前缀码和full binary trees,优先队列联系起来,可能这就是我们与天才的间隔。

你可能感兴趣的:(算法与数据结构,数据结构,算法)