8哈夫曼树
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
4
例1:霍夫曼树的构造过程
F : {7} {5} {2} {4}
7 5 2 4
F : {7} {5} {6}
7 5 6
2 4 合并{2} {4}
初始 F : {7} {11}
11 7 5 6
F : {18}
18 7 11
2 4 合并{5} {6}
5
6 2 4
5
合并{5} {6}
例2:设有4个字符d,i,a,n,出现的频度分别为7,5,2, 4
c
d
11110
1110
0.02
0.06
c
d
010
011
0.02 19 0.32
0.03 0.21 0.10
e
f g h
10
11111 01 1101
0.32
0.03 0.21 0.10
e
f g h
100
101 110 111
21 32 g e 0 17 0 1
7 a 10 h
Huffman码的WPL=2(0.19+0.32+0.21) + 4(0.07+0.06+0.10) +5(0.02+0.03)
指向左孩子
指向右兄弟
26
例如:
a
b c e
d f b e g h
a
c
d f
g
h
问:树转二叉树的“连线—抹线—旋转” 如 何由计算机自动实现? 答:用“左孩子右兄弟”表示法来存储即可。 存储Leabharlann Baidu过程就是转换的过程!
27
3、树和森林的遍历
树的遍历
遍历
深度遍历(先序、中序、后序) 广度遍历(层次)
• 先序遍历 访问根结点; 依次先序遍历根结点的每棵子树。 • 后序遍历 依次后序遍历根结点的每棵子树; 访问根结点。
b d e
a c f g
一、最优二叉树(霍夫曼树)
预备知识:若干术语 路 径: 由一结点到另一结点间的分支所构成
路径长度: 路径上的分支数目
a→e的路径长度= 2
树长度= 10 树的路径长度:从树根到每一结点的路径长度之和。 带权路径长度:结点到根的路径长度与结点上权的乘积 树中所有叶子结点的带权路径长度之和 树的带权路径长度: 霍 夫 曼 树: 带权路径长度最小的树。
二叉树的应用
平衡树—— 特点:左右子树深度差 ≤1 排序树—— 特点:“左小右大” 字典树—— 由字符串构成的二叉树排序树 判定树—— 例如,12个球只称3次分出轻重 带权树—— 特点:路径长度带权值 最优树—— 带权路径长度最短的树,又称 Huffman
树,用途之一是通信中的压缩编码。
1
6.5
Huffman树及其应用
29
森林的遍历
A
E
G
• 先序遍历 B C D F H I 若森林为空,返回; J 访问森林中第一棵树的根结点; 先序遍历第一棵树中根结点的子树森林; 先序遍历除去第一棵树之后剩余的树构成的森林。 • 中序遍历 若森林为空,返回; 中序遍历森林中第一棵树的根结点的子树森林; 访问第一棵树的根结点; 中序遍历除去第一棵树之后剩余的树构成的森林。
9
为清晰起见,重新排序为: w={2, 3, 6, 7, 10, 19, 21, 32} ×× w1={5, × × 6, 7, 10, 19, 21, 32} w2={7, × 10, × 11, 19, 21, 32} w3={11, × 17, × 19, 21, 32} w4={19, × 21, × 28, 32} w5={28,32,40} ×× w6={40,60} × × w7={100} 哈夫曼树 19 b
小结:哈夫曼树及其应用 1.Huffman算法的思路: ——权值大的结点用短路径,权值小的结点用长路径。 2.构造Huffman树的步骤: 对权值的合并、删除与替换 3. Huffman编码规则: 左“0” 右“1”,是一种前缀 码 也称为最小冗余编码、紧致码,等等,它是数据压缩 学的基础。
a
b d e c
2 3 4 5 6 7 b c d e
d
e f g f g h
f
g
h
8
h
25
3、用孩子兄弟表示法来存储
思路:用二叉链表来表示树,但链表中的两个 指针域含义不同。 左指针指向该结点的第一个孩子; 右指针指向该结点的下一个兄弟结点。
firstchild data nextsibling
例如:
b
树没有中序遍历(因子树不分左右)
a c d e
先序序列: a b c d e 后序序列: b d c e a
28
讨论:若采用“先转换,后遍历”方式,结果是否一样?
a a
先序遍历:a b c d e
b c
d
e
b c d e
中序遍历:b d c e a 后序遍历:d e c b a
结论: 1. 树的先序遍历二法相同; 2. 树的后序遍历相当于对应二叉树的中序遍历; 3. 树没有中序遍历,因为子树无左右之分。
根结点肯定 没有右孩子!
a
c e
i
d
e f f g h
18
g
h
讨论2:二叉树怎样还原为树?
要点:把所有右孩子变为兄弟!
a
b d c a
b i
c
i
e
f g h
d
e
f
g
h
19
讨论3:森林如何转为二叉树?
即F={T1, T2, …,Tm} B={root, LB, RB}
法一: ① 各树先各自转为二叉树; ② 依次连到前一个二叉树的右子树上。
30
例如:
A B
C E
G H I
J
ABCDEFGHIJ 先序序列:
D
F
中序序列: BCDAFEHJIG
讨论:若采用“先转换,后遍历”方式,结果是否相同?
A B C F D H I J
31
先序序列:A B C D E F G H I J
E G
中序序列:B C D A F E H J I G 结论:森林的先序和中序遍历在 两种方式下的结果相同。
8
霍夫曼编码的基本思想是:概率大的字符用短码,概率小的用 长码。由于霍夫曼树的WPL最小,说明编码所需要的比特数最 少。这种编码已广泛应用于网络通信中。
例2(严题集6.26③):假设用于通信的电文仅由8个字母
{a, b, c, d, e, f, g, h} 构成,它们在电文中出现的概率分别为{ 0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10} ,试为这8个字母设 计哈夫曼编码。如果用0~7的二进制编码方案又如何? 解:先将概率放大100倍,以方便构造哈夫曼树。 权值集合 w={7, 19, 2, 6, 32, 3, 21, 10}, 按哈夫曼树构造规则(合并、删除、替换),可得到哈夫曼树。
7
操作要点2:按左0右1对Huffman树的所有分支编号!
——将 Huffman树 与 Huffman编码
0 d 1
挂钩
0
i 0 a
1
1 n
Huffman编码结果:d=0, i=10, a=110, WPL=1bit×7+2bit×5+3bit(2+4)=35
n=111
特点:每一码都不是另一码的前缀,绝不会错译! 称为前缀码
怎样编码才能使它们组成的报文在网络中传得最快?
法1:等长编码。例如用二进制编码来实现。 取 d=00,i=01,a=10,n=11 法2:不等长编码,例如用哈夫曼编码来实现。 取 d=0; i=10, a=110, n=111 最快的编码是哪个? 是非等长的Huffman码!
怎样实现Huffman编码?先要构造Huffman树!
(最优前缀编码)
设想字符串为: 100个d,10个i,2个a,2个n 法1:228位 法2: 100x1+10x2+2x3+2x3= 132 位
6
构造Huffman树的步骤:
操作要点1:对权值的合并、删除与替换
——在权值集合{7,5,2,4}中,总是合并当前值最小的两个权
注:方框表示外结点(叶子,字符对应的权值), 圆框表示内结点(合并后的权值)。
100
40
21 32 g e 17 7 a
60
28 11 10 h 6 d 2 c 5 3 f
10
对应的哈夫曼编码(左0右1):
符 编码 频率 符 编码 频率
100
a
b
1100
00
0.07
0.19
a
b
000
001
0.07
0.19 0.06
0 b
0 40
1
1
0 60 1 28 1 0 6 d 0 2 c 11 1 5 1 3 f
=1.44+0.92+0.25=2.61
二进制码 WPL=3(0.19+0.32+0.21+0.07+0.06+0.10+0.02+0.03)=3
11
另一种结果表示:
12
例3(实验二):设字符集为26个英文字母,其出现频 度如下表所示。 要求编程实现: 先建哈夫曼树,再利用此树对报文“This program is my favorite”进行编码和译码。
i 57 s 51
t
80
13
提示1:霍夫曼树中各结点的结构可以定义为如下 5个分量: char weight parent lchild Rchild
提示2:霍夫曼树的存储结构可采用顺序存储结构:
将整个霍夫曼树的结点存储在一个数组中:HT[1..n]; 将结点的编码存储在HC[1..n]中。
提示3:霍夫曼树如何构造?构造好之后又如何求得 各结点对应的霍夫曼编码?——算法参见教材P147。
16
1. 树和森林与二叉树的转换
讨论1:树如何转为二叉树? 转换步骤: 加线 step1: 将树中同一结点的兄弟相连; step2: 保留结点的最左孩子连线,删除其它孩子 连线; 抹线 step3: 将同一孩子的连线绕左孩子旋转45度角。
旋转
17
树转二叉树举例: 方法:加线—抹线—旋转
兄弟相连 a b b c i d 长兄为父 孩子靠左
注:若圆满实现了此方案,实践表现成绩将以满分计。
字符 空格 频度 字符 频度 字符 频度 186 j 1 a 64 k 5 u 23 b 13 l 32 v 8 c 22 m 20 w 18 d 32 n 57 x 1
e
103 o 63 y 16
f 21 p 15 z 1 1
g 15 q
h 47 r 48
参考 资料 “数据结构”演示程序
14
二叉树小结
1、定义和性质 树
顺序结构
2、存储结构
链式结构
二叉链表
森林
二叉树
先序遍历
三叉链表
3、遍历
中序遍历
后序遍历
先序线索树
4、线索化:线索树 霍夫曼树
中序线索树 后序线索树
霍夫曼编码
15
6.4 树和森林
1. 树和森林与二叉树的转换 2. 树和森林的存储方式 3. 树和森林的遍历
要点:把最右边的子树变为森林,其余右子树变为兄弟
A A E C F G H I J B A C E G B C D F E H I
G
B
J
D
D
F
H
I J
22
2. 树和森林的存储方式
树有三种常用存储方式: ①双亲表示法 ②孩子表示法 ③孩子兄弟表示法
1、用双亲表示法来存储
思路:用一组连续空间来存储树的结点,同时在每个 结点中附设一个指示器,指示其双亲结点在链表中的 data parents 位置。
法二:森林直接变兄弟,再转为二叉树
(参见教材P138图6.17,两种方法都有转换示意图)
20
森林转二叉树举例:(法二)
A
B C D E G
A F
H
I
B E C F D H I J J H I G
J
A A B C E
G
D
F
兄弟相连 长兄为父 孩子靠左 头根为根
21
讨论4:二叉树如何还原为森林? 即B={root, LB, RB} F={T1, T2, …,Tm}
2
Huffman树简介:
Weighted Path Length
树的带权路径长度如何计算? WPL = 哈夫曼树则是:WPL 最小的树。
w kl k
k=1
n
经典之例:
4 d
2 c 7 a (b) 5 b
Huffman树
7 a
7 a
5
2 b c
4 d
5 b
2 c (c)
4 d
(a)
WPL=36
WPL=46
WPL= 35
3
构造霍夫曼树的基本思想: 权值大的结点用短路径,权值小的结点用长路径。 构造Huffman树的步骤(即Huffman算法):
(1) 由给定的 n 个权值{w0, w1, w2, …, wn-1},构造具有 n 棵扩充 二叉树的森林F = { T0, T1, T2, …, Tn-1 },其中每一棵扩充二叉树 Ti 只有一个带有权值 wi 的根结点,其左、右子树均为空。 (2) 重复以下步骤, 直到 F 中仅剩下一棵树为止: ① 在 F 中选取两棵根结点的权值最小的扩充二叉树, 做为左、 右子树构造一棵新的二叉树。置新的二叉树的根结点的权值为 其左、右子树上根结点的权值之和。 ② 在 F 中删去这两棵二叉树。 ③ 把新的二叉树加入 F。
1
data
parents
2 3 n
结点结构 树结构
23
例1: 双亲表示法
A
B D
H I E F
C G
0 1 2 3 4 5 6 7 8
A B C D E F G H I
-1
0 0 1 1 2 2 3 3
缺点:求结点的孩子时需要遍历整个结构。
24
2、用孩子表示法来存储
思路:将每个结点的孩子排列起来,形成一个带表头 (装父结点)的线性表(n个结点要设立n个链表); 再将n个表头用数组存放起来,这样就形成一个混合 结构。 1 a c b 例如:
例1:霍夫曼树的构造过程
F : {7} {5} {2} {4}
7 5 2 4
F : {7} {5} {6}
7 5 6
2 4 合并{2} {4}
初始 F : {7} {11}
11 7 5 6
F : {18}
18 7 11
2 4 合并{5} {6}
5
6 2 4
5
合并{5} {6}
例2:设有4个字符d,i,a,n,出现的频度分别为7,5,2, 4
c
d
11110
1110
0.02
0.06
c
d
010
011
0.02 19 0.32
0.03 0.21 0.10
e
f g h
10
11111 01 1101
0.32
0.03 0.21 0.10
e
f g h
100
101 110 111
21 32 g e 0 17 0 1
7 a 10 h
Huffman码的WPL=2(0.19+0.32+0.21) + 4(0.07+0.06+0.10) +5(0.02+0.03)
指向左孩子
指向右兄弟
26
例如:
a
b c e
d f b e g h
a
c
d f
g
h
问:树转二叉树的“连线—抹线—旋转” 如 何由计算机自动实现? 答:用“左孩子右兄弟”表示法来存储即可。 存储Leabharlann Baidu过程就是转换的过程!
27
3、树和森林的遍历
树的遍历
遍历
深度遍历(先序、中序、后序) 广度遍历(层次)
• 先序遍历 访问根结点; 依次先序遍历根结点的每棵子树。 • 后序遍历 依次后序遍历根结点的每棵子树; 访问根结点。
b d e
a c f g
一、最优二叉树(霍夫曼树)
预备知识:若干术语 路 径: 由一结点到另一结点间的分支所构成
路径长度: 路径上的分支数目
a→e的路径长度= 2
树长度= 10 树的路径长度:从树根到每一结点的路径长度之和。 带权路径长度:结点到根的路径长度与结点上权的乘积 树中所有叶子结点的带权路径长度之和 树的带权路径长度: 霍 夫 曼 树: 带权路径长度最小的树。
二叉树的应用
平衡树—— 特点:左右子树深度差 ≤1 排序树—— 特点:“左小右大” 字典树—— 由字符串构成的二叉树排序树 判定树—— 例如,12个球只称3次分出轻重 带权树—— 特点:路径长度带权值 最优树—— 带权路径长度最短的树,又称 Huffman
树,用途之一是通信中的压缩编码。
1
6.5
Huffman树及其应用
29
森林的遍历
A
E
G
• 先序遍历 B C D F H I 若森林为空,返回; J 访问森林中第一棵树的根结点; 先序遍历第一棵树中根结点的子树森林; 先序遍历除去第一棵树之后剩余的树构成的森林。 • 中序遍历 若森林为空,返回; 中序遍历森林中第一棵树的根结点的子树森林; 访问第一棵树的根结点; 中序遍历除去第一棵树之后剩余的树构成的森林。
9
为清晰起见,重新排序为: w={2, 3, 6, 7, 10, 19, 21, 32} ×× w1={5, × × 6, 7, 10, 19, 21, 32} w2={7, × 10, × 11, 19, 21, 32} w3={11, × 17, × 19, 21, 32} w4={19, × 21, × 28, 32} w5={28,32,40} ×× w6={40,60} × × w7={100} 哈夫曼树 19 b
小结:哈夫曼树及其应用 1.Huffman算法的思路: ——权值大的结点用短路径,权值小的结点用长路径。 2.构造Huffman树的步骤: 对权值的合并、删除与替换 3. Huffman编码规则: 左“0” 右“1”,是一种前缀 码 也称为最小冗余编码、紧致码,等等,它是数据压缩 学的基础。
a
b d e c
2 3 4 5 6 7 b c d e
d
e f g f g h
f
g
h
8
h
25
3、用孩子兄弟表示法来存储
思路:用二叉链表来表示树,但链表中的两个 指针域含义不同。 左指针指向该结点的第一个孩子; 右指针指向该结点的下一个兄弟结点。
firstchild data nextsibling
例如:
b
树没有中序遍历(因子树不分左右)
a c d e
先序序列: a b c d e 后序序列: b d c e a
28
讨论:若采用“先转换,后遍历”方式,结果是否一样?
a a
先序遍历:a b c d e
b c
d
e
b c d e
中序遍历:b d c e a 后序遍历:d e c b a
结论: 1. 树的先序遍历二法相同; 2. 树的后序遍历相当于对应二叉树的中序遍历; 3. 树没有中序遍历,因为子树无左右之分。
根结点肯定 没有右孩子!
a
c e
i
d
e f f g h
18
g
h
讨论2:二叉树怎样还原为树?
要点:把所有右孩子变为兄弟!
a
b d c a
b i
c
i
e
f g h
d
e
f
g
h
19
讨论3:森林如何转为二叉树?
即F={T1, T2, …,Tm} B={root, LB, RB}
法一: ① 各树先各自转为二叉树; ② 依次连到前一个二叉树的右子树上。
30
例如:
A B
C E
G H I
J
ABCDEFGHIJ 先序序列:
D
F
中序序列: BCDAFEHJIG
讨论:若采用“先转换,后遍历”方式,结果是否相同?
A B C F D H I J
31
先序序列:A B C D E F G H I J
E G
中序序列:B C D A F E H J I G 结论:森林的先序和中序遍历在 两种方式下的结果相同。
8
霍夫曼编码的基本思想是:概率大的字符用短码,概率小的用 长码。由于霍夫曼树的WPL最小,说明编码所需要的比特数最 少。这种编码已广泛应用于网络通信中。
例2(严题集6.26③):假设用于通信的电文仅由8个字母
{a, b, c, d, e, f, g, h} 构成,它们在电文中出现的概率分别为{ 0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10} ,试为这8个字母设 计哈夫曼编码。如果用0~7的二进制编码方案又如何? 解:先将概率放大100倍,以方便构造哈夫曼树。 权值集合 w={7, 19, 2, 6, 32, 3, 21, 10}, 按哈夫曼树构造规则(合并、删除、替换),可得到哈夫曼树。
7
操作要点2:按左0右1对Huffman树的所有分支编号!
——将 Huffman树 与 Huffman编码
0 d 1
挂钩
0
i 0 a
1
1 n
Huffman编码结果:d=0, i=10, a=110, WPL=1bit×7+2bit×5+3bit(2+4)=35
n=111
特点:每一码都不是另一码的前缀,绝不会错译! 称为前缀码
怎样编码才能使它们组成的报文在网络中传得最快?
法1:等长编码。例如用二进制编码来实现。 取 d=00,i=01,a=10,n=11 法2:不等长编码,例如用哈夫曼编码来实现。 取 d=0; i=10, a=110, n=111 最快的编码是哪个? 是非等长的Huffman码!
怎样实现Huffman编码?先要构造Huffman树!
(最优前缀编码)
设想字符串为: 100个d,10个i,2个a,2个n 法1:228位 法2: 100x1+10x2+2x3+2x3= 132 位
6
构造Huffman树的步骤:
操作要点1:对权值的合并、删除与替换
——在权值集合{7,5,2,4}中,总是合并当前值最小的两个权
注:方框表示外结点(叶子,字符对应的权值), 圆框表示内结点(合并后的权值)。
100
40
21 32 g e 17 7 a
60
28 11 10 h 6 d 2 c 5 3 f
10
对应的哈夫曼编码(左0右1):
符 编码 频率 符 编码 频率
100
a
b
1100
00
0.07
0.19
a
b
000
001
0.07
0.19 0.06
0 b
0 40
1
1
0 60 1 28 1 0 6 d 0 2 c 11 1 5 1 3 f
=1.44+0.92+0.25=2.61
二进制码 WPL=3(0.19+0.32+0.21+0.07+0.06+0.10+0.02+0.03)=3
11
另一种结果表示:
12
例3(实验二):设字符集为26个英文字母,其出现频 度如下表所示。 要求编程实现: 先建哈夫曼树,再利用此树对报文“This program is my favorite”进行编码和译码。
i 57 s 51
t
80
13
提示1:霍夫曼树中各结点的结构可以定义为如下 5个分量: char weight parent lchild Rchild
提示2:霍夫曼树的存储结构可采用顺序存储结构:
将整个霍夫曼树的结点存储在一个数组中:HT[1..n]; 将结点的编码存储在HC[1..n]中。
提示3:霍夫曼树如何构造?构造好之后又如何求得 各结点对应的霍夫曼编码?——算法参见教材P147。
16
1. 树和森林与二叉树的转换
讨论1:树如何转为二叉树? 转换步骤: 加线 step1: 将树中同一结点的兄弟相连; step2: 保留结点的最左孩子连线,删除其它孩子 连线; 抹线 step3: 将同一孩子的连线绕左孩子旋转45度角。
旋转
17
树转二叉树举例: 方法:加线—抹线—旋转
兄弟相连 a b b c i d 长兄为父 孩子靠左
注:若圆满实现了此方案,实践表现成绩将以满分计。
字符 空格 频度 字符 频度 字符 频度 186 j 1 a 64 k 5 u 23 b 13 l 32 v 8 c 22 m 20 w 18 d 32 n 57 x 1
e
103 o 63 y 16
f 21 p 15 z 1 1
g 15 q
h 47 r 48
参考 资料 “数据结构”演示程序
14
二叉树小结
1、定义和性质 树
顺序结构
2、存储结构
链式结构
二叉链表
森林
二叉树
先序遍历
三叉链表
3、遍历
中序遍历
后序遍历
先序线索树
4、线索化:线索树 霍夫曼树
中序线索树 后序线索树
霍夫曼编码
15
6.4 树和森林
1. 树和森林与二叉树的转换 2. 树和森林的存储方式 3. 树和森林的遍历
要点:把最右边的子树变为森林,其余右子树变为兄弟
A A E C F G H I J B A C E G B C D F E H I
G
B
J
D
D
F
H
I J
22
2. 树和森林的存储方式
树有三种常用存储方式: ①双亲表示法 ②孩子表示法 ③孩子兄弟表示法
1、用双亲表示法来存储
思路:用一组连续空间来存储树的结点,同时在每个 结点中附设一个指示器,指示其双亲结点在链表中的 data parents 位置。
法二:森林直接变兄弟,再转为二叉树
(参见教材P138图6.17,两种方法都有转换示意图)
20
森林转二叉树举例:(法二)
A
B C D E G
A F
H
I
B E C F D H I J J H I G
J
A A B C E
G
D
F
兄弟相连 长兄为父 孩子靠左 头根为根
21
讨论4:二叉树如何还原为森林? 即B={root, LB, RB} F={T1, T2, …,Tm}
2
Huffman树简介:
Weighted Path Length
树的带权路径长度如何计算? WPL = 哈夫曼树则是:WPL 最小的树。
w kl k
k=1
n
经典之例:
4 d
2 c 7 a (b) 5 b
Huffman树
7 a
7 a
5
2 b c
4 d
5 b
2 c (c)
4 d
(a)
WPL=36
WPL=46
WPL= 35
3
构造霍夫曼树的基本思想: 权值大的结点用短路径,权值小的结点用长路径。 构造Huffman树的步骤(即Huffman算法):
(1) 由给定的 n 个权值{w0, w1, w2, …, wn-1},构造具有 n 棵扩充 二叉树的森林F = { T0, T1, T2, …, Tn-1 },其中每一棵扩充二叉树 Ti 只有一个带有权值 wi 的根结点,其左、右子树均为空。 (2) 重复以下步骤, 直到 F 中仅剩下一棵树为止: ① 在 F 中选取两棵根结点的权值最小的扩充二叉树, 做为左、 右子树构造一棵新的二叉树。置新的二叉树的根结点的权值为 其左、右子树上根结点的权值之和。 ② 在 F 中删去这两棵二叉树。 ③ 把新的二叉树加入 F。
1
data
parents
2 3 n
结点结构 树结构
23
例1: 双亲表示法
A
B D
H I E F
C G
0 1 2 3 4 5 6 7 8
A B C D E F G H I
-1
0 0 1 1 2 2 3 3
缺点:求结点的孩子时需要遍历整个结构。
24
2、用孩子表示法来存储
思路:将每个结点的孩子排列起来,形成一个带表头 (装父结点)的线性表(n个结点要设立n个链表); 再将n个表头用数组存放起来,这样就形成一个混合 结构。 1 a c b 例如: