哈夫曼树
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
哈夫曼树及其应用 1.问题的提出 问题的提出
在程序设计中,常用一个代码来表示一个 元素,标准ASCII码就是一个例子。它用log2128 即7位提供了128个不同的代码来表示ASCII表中 的128个字符。假设所有代码都等长,则表示n 个不同的代码需要log2n位,称为固定长度编码 (如ASCII码)。如果每个字符的使用频率相等, 则固定长度编码的空间效率最高。但事实上,每 个字符的使用频率并非一样。
考虑这样一棵带权二叉树,即给定一组 权值: W={w1,w2,…,wn} 使得二叉树的每个叶结点有一个权值,定义二 叉树的带权路径长度为:
WPL =
n
∑wl
k =1
k k
lk为根到叶结点wk的路径长度。则其中带 权路径长度最小的二叉树称作哈夫曼树或最优 二叉树。业已证明:利用哈夫曼树构造的编码 其总码长是最短的。
树的路径长度是从树的根结点到树的各个结点 的路径长度之和,记作TL,例如上图所示的三棵二 叉树的路径长度分别为: TL(a)=0+1+1+2+2+3+3+4+4=20 TL(b)=0+1+1+2+2+2+2+3+3=16 TL(c)=0+1+1+2+2+2+2+3+3=16
将上述概念推广到一般情况,考虑带权的结点, 则某结点的带权路径长度是指该结点的路径长度与 该结点上权的乘积,二叉树的带权路径长度是指所 有带权叶子结点的带权路径长度之和。 假定一个有n个权值的集合{w1,w2,…,wn}, 其中wi≥0(1≤i≤n),若T是一个有n个叶子的二叉 树,而且将权w1,w2,…,wn分别赋给树的n个叶 子,则n个叶子的二叉树带权路径长度定义为:
1 107 1 65 0
L 42
0
C 32
1
33
F
0
F 24
1 9 0
Z 2
K
1
K 7
L U Z
哈夫曼编码的效率。 我们定义该编码方案的平均编码长度为: B(T)=(c1p1+ c2p2 +…+ cnpn)/pt 其中: ci和pi是字符集中第i个字符的代码长度及 其相对频率,pt是字符集的总频率。对本例计算平 均编码长度≈2.565 若采用固定长度编码,每个字母需log28=3位, 而哈夫曼编码只需2.565位,节省空间约12%。 哈夫曼编码对于典型的文本文件将比ASCII编 码节省约40%的空间。
① 将给定的n个权值W={w1,w2,…,wn}构成n棵 二叉树的集合即森林F={T1,T2,…,Tn},其中每棵树Ti 的初值为只有一个权值wi 的根结点,其左右子树为 空; ② 在F中选取两棵根结点之权值为最小的树作 为左、右子树构成一棵新的二叉树,该新二叉树的根 结点的权值为其左、右子树的根结点权值之和。 ③ 从F中删除这两棵树,同时将新得到的二叉 树加到F中。 ④ 重复②和③,直到F中只有一棵树。这棵树 就是哈夫曼树。 哈夫曼树。
用途:用于通信和数据传送中字符的二进制编码,可以 用途 使文件编码总长度最短。 F K L U Z 例字符集: C D E 频 率:32 42 120 24 7 42 37 2
306
0
1 186
C D E
1110 101 0 11110 111111 110 100 111110
E 79 0 1 120 0 U D 37 42
WPL =
n
k =1 其中n为叶子结点数,lk为根到叶结点wk的 路径长度。 最优二叉树(哈夫曼树 哈夫曼树): 最优二叉树 哈夫曼树 :n个带权叶子结点构成的 所有二叉树中,带权路径长度WPL最小的二叉 树。
∑wl
k k
2. 建立哈夫曼树(最优二叉树)的方法 建立哈夫曼树(最优二叉树) 1952年由 年由D.A.Huffman提出的哈夫曼算法: 提出的哈夫曼算法: 年由 提出的哈夫曼算法
10000(5%+2×15%+3×40%+4×40%)=31500次
也即按如上图所示的分支结构与程序段,则 10000个数据需执行判断31500次。
下面我们就利用哈夫曼树寻找一棵最佳判定树, 即总的比较次数最少的判定树。
<80 <70 <60 C D B <90 A
E
需比较的次数应为10000(3×20%+2×80%) =22000次,很明显,两种方法的效率是不一样的。
下面给出的是某个文献中其中8个英文字母的使用 频率: 字母:C D E F K L U Z 频率:32 42 120 24 7 42 37 2 若采用ASCII编码,单词“DEED”和“FUZZ”占 用等长的空间。但若给出现频率高的字符以较短的编 码,给出现频率低的字符以较长的编码,即使用不等 长编码,也许可以缩短文件的总的码长——总的存储 空间减少了。这个概念就是今天使用的文件压缩技术 的核心。 那么,如何给上述8个字母编码,以保证实际数 据文件的总码长最短呢? 考虑:1.出现频率高的字符用短编码 2.译码时不会出现错误 解决方法:哈夫曼树
编码 0110 10 1110 1111 110 00 0111 010
Fra Baidu bibliotek
以上的①∼⑧分别代表 8 个字符。
发送一段编码:0000011011010010,
接收方译码:⑥⑥①⑤②⑧
其中wi为叶子i的权,li为根结点到叶子i之间路 径长度,在权w1,w2,w3,…,wn的二叉树中, WTL最小的二叉树称为哈夫曼树或最优树。
基本术语
结点的权: 结点的权:树中的结点上赋予的一定意义的数值。 结点的带权路径长度:从树根结点到该结点之间 结点的带权路径长度 的路径长度与该结点上权的乘积。 树的带权路径长度:树中所有叶子结点的带权路 树的带权路径长度 径长度之和。通常记作
前缀编码
任一个字符的编码都不是另一个字符的编码的前 缀。 假如有A,BC,D四个字符,设计的前缀编码分别为 0,10,110,111,任一个的编码都不是另一个编码的 前缀. 哈夫曼编码
哈夫曼编码的构造方法
(1)利用字符集中每个字符的使用频率作为权 值构造一个哈夫曼树; (2)从根结点开始,为到每个叶子结点路径上 0 1 的左分支赋予0,右分支赋予1,并从根到叶子方向 形成该叶子结点的编码。
练习:假设有一个电文字符集中有8个字符,每个字 符的使用频率分别为 {0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11},设计哈 夫曼编码。
字符 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧
字符的使用频率 0.05 0.29 0.07 0.08 0.14 0.23 0.03 0.11
if (socre<60) printf(“bad”); else if (socre<70) printf(“pass”); else if (score<80) printf(“general”); else if (score<90) printf(“good”); esle printf(“very good”);
在实际应用中,往往各个分数段的分布并不是均匀 的。下面就是在一次考试中某门课程的各分数段的分布情 况:
分数 比例 0~59 0.05 60~69 0.15 70~79 0.40 80~89 0.30 90~100 0.10
判定过程如图所示:
学生的成绩数据共10000个,5%的数据需1次比 较,15%的数据需2次比较,40%的数据需3次比较, 40%的数据需4次比较,因此10000个数据比较的次 数为
基本思想:使权大的结点靠近根。 基本思想
例1:{ : 5 10 12 13 30 }
15 第一步 5 第二步 15 5 10 10
12
13
30
25 12 13
30
第三步
40 30 5 10 70 30 12 13
第四步
5
10
12
13
WPL=5×3+10×3+12×3+13×3+30×1=150 由图可以看出,哈夫曼树的结点的度数为0 或2,没有度为1的结点
预备知识
先介绍二叉树路径长度的概念。 树中一个结点到另一个结点之间的路径长度是 这两个结点之间的分支所构成的路径上的分支数。 由树的定义可知,从根结点到达树的每个结点 有且仅有一种路径。我们规定根的层数为1,如果 树中某个结点的层次为k,则从根到该结点的路径长 度为(k-1)。
如下图为三棵二叉树,其中图(a)所示的二叉 树中,从根A到B,C,D,E,F,G,H,I的路径长 度分别为1,1,2,2,3,3,4,4。
二、前缀编码
在电文传输中,需要将电文中出现的每个字符 进行二进制编码。在设计编码时遵守两个原则: (1)发送方传输的二进制编码,到接收方解 码后必须具有唯一性,即解码结果与发送方发送的 电文完全一样; (2)发送的二进制编码尽可能地短。 编码方法: 1. 等长编码:译码简单且具有唯一性,但编 码长度不是最短; 2. 不等长编码:译码可能不唯一 解决方法:前缀编码
哈夫曼编码是不等长编码 哈夫曼编码是前缀编码,即任一字符的编码都 不是另一字符编码的前缀 哈夫曼编码树中没有度为1的结点。若叶子结点 的个数为n,则哈夫曼编码树的结点总数为 2n-1 发送过程:根据由哈夫曼树得到的编码表送出 字符数据 接收过程:按左0、右1的规定,从根结点走到 一个叶结点,完成一个字符的译码。反复此过 程,直到接收数据结束
练习: 假设有一组权值{5,29,7,8,14,23,3,11},利 用这组权值构造哈夫曼树。
5
29
7
8
14
23
3
11
哈夫曼树的应用
一、判定问题
将学生的百分制成绩表转换为五分制成绩,大于 或等于90分者表为“A”,80~90分为“B”, 70~79分为“C”,60~69为“D”,小于60分为 “E”。 程序实现很简单:
在程序设计中,常用一个代码来表示一个 元素,标准ASCII码就是一个例子。它用log2128 即7位提供了128个不同的代码来表示ASCII表中 的128个字符。假设所有代码都等长,则表示n 个不同的代码需要log2n位,称为固定长度编码 (如ASCII码)。如果每个字符的使用频率相等, 则固定长度编码的空间效率最高。但事实上,每 个字符的使用频率并非一样。
考虑这样一棵带权二叉树,即给定一组 权值: W={w1,w2,…,wn} 使得二叉树的每个叶结点有一个权值,定义二 叉树的带权路径长度为:
WPL =
n
∑wl
k =1
k k
lk为根到叶结点wk的路径长度。则其中带 权路径长度最小的二叉树称作哈夫曼树或最优 二叉树。业已证明:利用哈夫曼树构造的编码 其总码长是最短的。
树的路径长度是从树的根结点到树的各个结点 的路径长度之和,记作TL,例如上图所示的三棵二 叉树的路径长度分别为: TL(a)=0+1+1+2+2+3+3+4+4=20 TL(b)=0+1+1+2+2+2+2+3+3=16 TL(c)=0+1+1+2+2+2+2+3+3=16
将上述概念推广到一般情况,考虑带权的结点, 则某结点的带权路径长度是指该结点的路径长度与 该结点上权的乘积,二叉树的带权路径长度是指所 有带权叶子结点的带权路径长度之和。 假定一个有n个权值的集合{w1,w2,…,wn}, 其中wi≥0(1≤i≤n),若T是一个有n个叶子的二叉 树,而且将权w1,w2,…,wn分别赋给树的n个叶 子,则n个叶子的二叉树带权路径长度定义为:
1 107 1 65 0
L 42
0
C 32
1
33
F
0
F 24
1 9 0
Z 2
K
1
K 7
L U Z
哈夫曼编码的效率。 我们定义该编码方案的平均编码长度为: B(T)=(c1p1+ c2p2 +…+ cnpn)/pt 其中: ci和pi是字符集中第i个字符的代码长度及 其相对频率,pt是字符集的总频率。对本例计算平 均编码长度≈2.565 若采用固定长度编码,每个字母需log28=3位, 而哈夫曼编码只需2.565位,节省空间约12%。 哈夫曼编码对于典型的文本文件将比ASCII编 码节省约40%的空间。
① 将给定的n个权值W={w1,w2,…,wn}构成n棵 二叉树的集合即森林F={T1,T2,…,Tn},其中每棵树Ti 的初值为只有一个权值wi 的根结点,其左右子树为 空; ② 在F中选取两棵根结点之权值为最小的树作 为左、右子树构成一棵新的二叉树,该新二叉树的根 结点的权值为其左、右子树的根结点权值之和。 ③ 从F中删除这两棵树,同时将新得到的二叉 树加到F中。 ④ 重复②和③,直到F中只有一棵树。这棵树 就是哈夫曼树。 哈夫曼树。
用途:用于通信和数据传送中字符的二进制编码,可以 用途 使文件编码总长度最短。 F K L U Z 例字符集: C D E 频 率:32 42 120 24 7 42 37 2
306
0
1 186
C D E
1110 101 0 11110 111111 110 100 111110
E 79 0 1 120 0 U D 37 42
WPL =
n
k =1 其中n为叶子结点数,lk为根到叶结点wk的 路径长度。 最优二叉树(哈夫曼树 哈夫曼树): 最优二叉树 哈夫曼树 :n个带权叶子结点构成的 所有二叉树中,带权路径长度WPL最小的二叉 树。
∑wl
k k
2. 建立哈夫曼树(最优二叉树)的方法 建立哈夫曼树(最优二叉树) 1952年由 年由D.A.Huffman提出的哈夫曼算法: 提出的哈夫曼算法: 年由 提出的哈夫曼算法
10000(5%+2×15%+3×40%+4×40%)=31500次
也即按如上图所示的分支结构与程序段,则 10000个数据需执行判断31500次。
下面我们就利用哈夫曼树寻找一棵最佳判定树, 即总的比较次数最少的判定树。
<80 <70 <60 C D B <90 A
E
需比较的次数应为10000(3×20%+2×80%) =22000次,很明显,两种方法的效率是不一样的。
下面给出的是某个文献中其中8个英文字母的使用 频率: 字母:C D E F K L U Z 频率:32 42 120 24 7 42 37 2 若采用ASCII编码,单词“DEED”和“FUZZ”占 用等长的空间。但若给出现频率高的字符以较短的编 码,给出现频率低的字符以较长的编码,即使用不等 长编码,也许可以缩短文件的总的码长——总的存储 空间减少了。这个概念就是今天使用的文件压缩技术 的核心。 那么,如何给上述8个字母编码,以保证实际数 据文件的总码长最短呢? 考虑:1.出现频率高的字符用短编码 2.译码时不会出现错误 解决方法:哈夫曼树
编码 0110 10 1110 1111 110 00 0111 010
Fra Baidu bibliotek
以上的①∼⑧分别代表 8 个字符。
发送一段编码:0000011011010010,
接收方译码:⑥⑥①⑤②⑧
其中wi为叶子i的权,li为根结点到叶子i之间路 径长度,在权w1,w2,w3,…,wn的二叉树中, WTL最小的二叉树称为哈夫曼树或最优树。
基本术语
结点的权: 结点的权:树中的结点上赋予的一定意义的数值。 结点的带权路径长度:从树根结点到该结点之间 结点的带权路径长度 的路径长度与该结点上权的乘积。 树的带权路径长度:树中所有叶子结点的带权路 树的带权路径长度 径长度之和。通常记作
前缀编码
任一个字符的编码都不是另一个字符的编码的前 缀。 假如有A,BC,D四个字符,设计的前缀编码分别为 0,10,110,111,任一个的编码都不是另一个编码的 前缀. 哈夫曼编码
哈夫曼编码的构造方法
(1)利用字符集中每个字符的使用频率作为权 值构造一个哈夫曼树; (2)从根结点开始,为到每个叶子结点路径上 0 1 的左分支赋予0,右分支赋予1,并从根到叶子方向 形成该叶子结点的编码。
练习:假设有一个电文字符集中有8个字符,每个字 符的使用频率分别为 {0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11},设计哈 夫曼编码。
字符 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧
字符的使用频率 0.05 0.29 0.07 0.08 0.14 0.23 0.03 0.11
if (socre<60) printf(“bad”); else if (socre<70) printf(“pass”); else if (score<80) printf(“general”); else if (score<90) printf(“good”); esle printf(“very good”);
在实际应用中,往往各个分数段的分布并不是均匀 的。下面就是在一次考试中某门课程的各分数段的分布情 况:
分数 比例 0~59 0.05 60~69 0.15 70~79 0.40 80~89 0.30 90~100 0.10
判定过程如图所示:
学生的成绩数据共10000个,5%的数据需1次比 较,15%的数据需2次比较,40%的数据需3次比较, 40%的数据需4次比较,因此10000个数据比较的次 数为
基本思想:使权大的结点靠近根。 基本思想
例1:{ : 5 10 12 13 30 }
15 第一步 5 第二步 15 5 10 10
12
13
30
25 12 13
30
第三步
40 30 5 10 70 30 12 13
第四步
5
10
12
13
WPL=5×3+10×3+12×3+13×3+30×1=150 由图可以看出,哈夫曼树的结点的度数为0 或2,没有度为1的结点
预备知识
先介绍二叉树路径长度的概念。 树中一个结点到另一个结点之间的路径长度是 这两个结点之间的分支所构成的路径上的分支数。 由树的定义可知,从根结点到达树的每个结点 有且仅有一种路径。我们规定根的层数为1,如果 树中某个结点的层次为k,则从根到该结点的路径长 度为(k-1)。
如下图为三棵二叉树,其中图(a)所示的二叉 树中,从根A到B,C,D,E,F,G,H,I的路径长 度分别为1,1,2,2,3,3,4,4。
二、前缀编码
在电文传输中,需要将电文中出现的每个字符 进行二进制编码。在设计编码时遵守两个原则: (1)发送方传输的二进制编码,到接收方解 码后必须具有唯一性,即解码结果与发送方发送的 电文完全一样; (2)发送的二进制编码尽可能地短。 编码方法: 1. 等长编码:译码简单且具有唯一性,但编 码长度不是最短; 2. 不等长编码:译码可能不唯一 解决方法:前缀编码
哈夫曼编码是不等长编码 哈夫曼编码是前缀编码,即任一字符的编码都 不是另一字符编码的前缀 哈夫曼编码树中没有度为1的结点。若叶子结点 的个数为n,则哈夫曼编码树的结点总数为 2n-1 发送过程:根据由哈夫曼树得到的编码表送出 字符数据 接收过程:按左0、右1的规定,从根结点走到 一个叶结点,完成一个字符的译码。反复此过 程,直到接收数据结束
练习: 假设有一组权值{5,29,7,8,14,23,3,11},利 用这组权值构造哈夫曼树。
5
29
7
8
14
23
3
11
哈夫曼树的应用
一、判定问题
将学生的百分制成绩表转换为五分制成绩,大于 或等于90分者表为“A”,80~90分为“B”, 70~79分为“C”,60~69为“D”,小于60分为 “E”。 程序实现很简单: