190 likes | 287 Views
A. B. C. D. E. F. 产生三种遍历方式的结点列表的方法. 从根结点出发,依逆时针方向沿树的外缘绕行,绕行途中可能多次通过同一点。如果按第一次经过的时间次序将各结点列表,就得到先序列表;如果按最后一次经过的时间次序列表,就得到后序列表;如果将叶子结点在第一次经过时列出,内部结点在第二次经过时列出,则为中序列表。. 二叉树的恢复. 由先序和中序恢复 1 )先根据先序序列确定根结点,根据中序序列左子树和右子树。 2 )用上述方法,在分别找出左子树的根及其左、右子树直到结束。 由后序和中序恢复 1 )先根据后序序列确定根结点,根据中序序列左子树和右子树。
E N D
A B C D E F 产生三种遍历方式的结点列表的方法 从根结点出发,依逆时针方向沿树的外缘绕行,绕行途中可能多次通过同一点。如果按第一次经过的时间次序将各结点列表,就得到先序列表;如果按最后一次经过的时间次序列表,就得到后序列表;如果将叶子结点在第一次经过时列出,内部结点在第二次经过时列出,则为中序列表。
二叉树的恢复 • 由先序和中序恢复 1)先根据先序序列确定根结点,根据中序序列左子树和右子树。 2)用上述方法,在分别找出左子树的根及其左、右子树直到结束。 • 由后序和中序恢复 1)先根据后序序列确定根结点,根据中序序列左子树和右子树。 2)用上述方法,在分别找出左子树的根及其左、右子树直到结束。
0 Lchild 指向左孩子 Ltag= 1 Lchild 指向前驱 0 Rchild 指向右孩子 Rtag= 1 Rchild 指向后继 线索二叉树 有n个结点的二叉链表中一定有n+1个空指针,因此可以对这些空指针加以利用。 • 定义 加入了指向在某种遍历次序下的前驱和后继的指针的二叉树称为线索二叉树。 • 实现 既然是用存储左、右子树的指针的指针域来存储前驱 和后继,那怎么分辨呢? 增加两个标志域
将树和森林转换为二叉树 由于二叉树可以用二叉链表表示,为了使一般树也能用二叉链表表示,必须找出树与二叉树之间的关系。 这样,给定一棵树,可以找到唯一的一棵二叉树与之对应。 (1)树转换为二叉树 方法:· 对每个孩子进行从左到右的排序; · 在兄弟之间加一条连线; · 对每个结点,除了左孩子外,去除其与其余孩子之间的联系; · 以根结点为轴心,将整个树顺时针转45度。
A (b) (a) A B C D C D B E F G H I F H I E G A A B (c) C (d) E D B C D G F H E F G H I I 树转换为二叉树
E A A E G F G B B C D H F I H C J D J I A A G E E B F G B H C F C H J I D D J I (2) 森林转换为二叉树 方法: · 将各棵树分别转成二叉树; · 把每棵树的根结点用线连起来; · 以第一棵树的根结点作为二叉树的根结点,按顺时针方向旋转。
哈夫曼树及其应用 1、哈夫曼树 树的路径长度的概念: 从一个结点到另一个结点之间的分支数目称为这对结点之间的路径长度。 树的路径长度是从树的根到每一结点的路径长度之和。
树的路径长度用PL表示。 1 2 3 4 5 6 7 PL=0+1+1+2+2+2+2=10
树的路径长度用PL表示。 1 1 2 3 2 3 4 5 4 5 6 7 6 7 PL=0+1+1+2+2+2+2=10 PL=0+1+1+2+2+3+3=12
a b c d 7 5 2 4 WPL=7*2+5*2+2*2+4*2=36 结点带权的路径长度: 从该结点到树根之间的路径长度与结点上权的乘积。 树的带权路径长度: 树中叶子结点带权路径长度之和。
a b c d 7 5 2 4 WPL=7*2+5*2+2*2+4*2=36 树的带权路径长度记作: 其中:Wk为树中每个叶子结点的权; L k为每个叶子结点到根的路径长度。 WPL最小的二叉树就称作最优二叉树或哈夫曼树 。
a b c d 7 5 2 4 WPL=7*2+5*2+2*2+4*2=36 c 2 7 a 4 d 5 b a b 2 4 c d 7 5 WPL=7*3+5*3+2*1+4*2=46 WPL=7*1+5*2+2*3+4*3=35 哈夫曼树 (最优树) 加权路径长度最小的二叉树就是哈夫曼树。 公式:
2、哈夫曼树的构造 例:给定权值{7,5,2,4},构造哈夫曼树。 6 7 5 7 5 2 4 c d a b c d (b) (a) 18 11 7 11 7 a b b 6 5 5 c d c d (c) (d) 2 4 方法: (1)由原始数据生成森林; (2) 在森林中选取两棵根结点权值最小的和次小的二叉树作为左右子树构造一棵新的二叉树,其根结点的权值为左右子树根结点权值之和。规定左子树根结点的权值小于右子树根结点的权值。 (3)将新的二叉树加入到森林F中,去除原两棵权值最小的树; (4)重复2、3步骤,直至F中只剩一棵树为止。
a<60 N Y 不及格 a<70 Y N a<80 及格 N Y 中等 a<90 Y N 良好 优秀 (a) 3、哈夫曼树的应用 (1)判定树 在解决某些判定问题时,利用哈夫曼树可以得到最佳判定算法。 例1 将学生百分成绩按分数段分级的程序。 若学生成绩分布是均匀的,可用图(a)二叉树结构来实现。 输入10000个数据,则需进行31500次比较。
学生成绩分布不是均匀的情况: 70≤a≤ 80 N Y 中等 80≤a<90 Y N 60≤a<70 良好 Y N a<60 及格 Y N a<80 N 不及格 优秀 Y a<90 Y a<70 N Y Y 中等 良好 优秀 a<60 Y N (c) 不及格 及格 以比例数为权构造一棵哈夫曼树,如(b)判断树所示。 输入10000个数据,仅需进行22000次比较。 再将每一比较框的两次比较改为一次,可得到(c)判定树。 (b)
14 0 1 6 8 0 1 0 1 3 3 4 4 0 1 T ; A 2 2 C S (2)哈夫曼编码-----利用哈夫曼树构造通讯中电文编码(前缀码) 例2:要传输的电文是{CAS;CAT;SAT;AT} 要传输的字符集是 D={C,A,S,T, ;} 每个字符出现的频率是W={ 2,4, 2,3, 3 } 各字符编码是 T ; A C S 00 01 10 110 111 上述电文编码: 11010111011101000011111000011000 方法: (1)用{ 2,4, 2,3, 3 }作为叶子结点的权值生成一棵哈夫曼树,并将对应权值wi的叶子结点注明对应的字符; (2)约定左分支表示字符“0”,右分支表示字符‘1’ (3)从叶子结点开始,顺着双亲反推上去,直到根结点,路径上的‘0’或‘1’连接的序列就是结点对应的字符的二进制编码的逆序。 注意:编码的总长度恰好为哈夫曼树的带权路径长。
贪心算法 例:设有四种硬币:0.25元、 0.1元、 0.05元、 0.01元。 现要找给顾客0.63元。 找硬币的算法:首先选出一个面值不超过0.63元 的最大硬币,即0.25元,然后从0.63元中减去0.25 元,剩下0.38元;再选出一个面值不超过0.63元的 最大硬币,即0.25元,如此下去。即贪心算法。 • 定义 通过一系列的选择来得到问题的一个解,它所做的每一个选择都是在当前状态下某种意义的最好选择,并希望通过每次所做的贪心选择导致最终结果是最优解。 拿出2个0.25元的、1个0.1元的、3个0.01元的硬币
用贪心算法求解的问题应具有的性质 • 贪心选择性质 即所求问题的整体最优解可以通过一系列的局部最优的选择来达到。 • 最优子结构性质 若一个问题的最优解包含着它的子问题的最优解,则次问题具有最优子结构性质。这是可否用贪心算法求解的一个关键问题,但并不是绝对。
0-1背包问题:给定n种物品和一背包。物品i的重量是Wi,其0-1背包问题:给定n种物品和一背包。物品i的重量是Wi,其 价值为Vi,背包的容量为W。问如何选择物品装入,使背包 中的物品的总价值最大?在选择物品时,对每种物品i只有 两种选择,要么装入,要么不装,不能将物品i装入多次,也 不能只装入物品i的一部分。 背包问题:与0-1背包问题相似,所不同的只是在选择物品i的 时候,可以选择物品i的一部分而不是全部。 问题:这两类问题极为相似,都具有最优子结构性 质,那是否都可以用贪心算法求解呢? 不是!背包问题可以用贪心算法求解,但0-1背包问 题却不能! 对于0-1背包问题,贪心算法之所以不能得到最优解,是因 为无法保证最终能将背包装满。部分背包空间的空闲使得每 公斤背包空间具有的价值降低了!