More Related Content More from Wang Yizhe (12) 第六章11. 6.1 树的类型定义
6. 2 二叉树的类型定义
6.3 二叉树的存储结构
6.4 二叉树的遍历
6.5 线索二叉
树 6.6 树和森林的表示方法
6.7 树和森林的遍历
6.8 哈夫曼树与哈夫曼编码
3. 数据对象 D :
D 是具有相同特性的数据元素的集合。
数据关系 R :
若 D 为空集,则称为空树 。
否则 :
(1) 在 D 中存在唯一的称为根的数据元素 root ;
(2) 当 n>1 时,其余结点可分为 m (m>0) 个互
不相交的有限集 T1, T2, …, Tm ,其中每一
棵子集本身又是一棵符合本定义的树,
称为根 root 的子树。
4. 例如 : A
B C D
E F G H I J
K L M
A( B(E, F(K, L)), C(G), D(H, I, J(M)) )
树根 T1 T2 T3
5. 基本操作:
查 找
类
插 入 类
删 除 类
6. 查找类:
Root(T) // 求树的根结点
Value(T, cur_e) // 求当前结点的元素值
Parent(T, cur_e) // 求当前结点的双亲结点
LeftChild(T, cur_e) // 求当前结点的最左孩子
RightSibling(T, cur_e) // 求当前结点的右兄弟
TreeEmpty(T) // 判定树是否为空树
TreeDepth(T) // 求树的深度
TraverseTree( T, Visit() ) // 遍历
9. 例如 : A
B C D
E F G H I J
K L M
A( B(E, F(K, L)), C(G), D(H, I, J(M)) )
树根 T1 T2 T3
10. 树形图表示的例
子
A
A BE
A K
B C D H D L
E B C F
E F GH I J KL F M J G
I D
C H
K L M M
G I
J
嵌套集合表示法 凹入表示法
( A(B(E(K,L),F),C(G),D(H(M),I,J)))
广义表表示法
12. 线性结构 树型结构
第一个数据元素 根结点
( 无前驱 ) ( 无前驱 )
最后一个数据元素 多个叶子结点
( 无后继 ) ( 无后继 )
其它数据元素 其它数据元素
( 一个前驱、 ( 一个前驱、
一个后继 ) 多个后继 )
14. 结点 数据元素 + 若干指向子树的分支
:
结点的度 : 分支的个数
树的度 :树中所有结点的度的最大值
D
叶子结点 : 度为零的结点
H I J
分支结点 : 度大于零的结点
M
15. ( 从根到结点的 ) 路径 : A
由从根到该结点
B C D
所经分支和结点构成
E F G H I J
孩子结点、双亲结点
K L M
兄弟结点、堂兄弟
祖先结点、子孙结点
结点的层次 : 假设根结点的层次为 1 ,
第 l 层的结点的子树根结
点的层次为 l+1
树的深度:
树中叶子结点所在的最大层次
16. 有向树:
( 1 ) 有确定的根;
( 2 ) 树根和子树根之间为有向关系。
有序树:
子树之间存在确定的次序关系。
无序树:
子树之间不存在确定的次序关系。
17. F root
森林: A
是 m ( m≥ 0 )棵互 B C D
不相交的树的集合 E F G H I J
K L M
任何一棵非空树是一个二元组
Tree = ( root , F )
其中: root 被称为根结点
F 被称为子树森林
22. Root(T); Value(T, e); Parent(T, e);
LeftChild(T, e); RightChild(T, e);
LeftSibling(T, e); RightSibling(T, e);
BiTreeEmpty(T); BiTreeDepth(T);
PreOrderTraverse(T, Visit());
InOrderTraverse(T, Visit());
PostOrderTraverse(T, Visit());
LevelOrderTraverse(T, Visit());
26. l 性质 1 :
在二叉树的第 i 层上至多
有 2i-1 个结点。 (i≥ 1)
用归纳法证明 :
归纳基: 1 层时,只有一个根结点:
i=
2i-1 = 20 = 1 ;
归纳假设:假设对所有的 j , 1≤ j < i ,命题成立;
归纳证明:二叉树上每个结点至多有两棵子树,
则第 i 层的结点数 = 2i-2× 2 = 2i-1 。
27. l性质 2 :
深度为 k 的二叉树上至多含
2k-1 个结点( k≥ 1 )。
证明:
基于上一条性质,深度为 k 的二
叉树上的结点数至多为
20+21+ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ +2k-1 = 2k-1 。
28. l 性质 3 :
对任何一棵二叉树,若它含有 n0 个
叶子结点、 n2 个度为 2 的结点,则必
存在关系式: n0 = n2+1 。
证明:
设 二叉树上结点总数 n = n0 + n1 + n2
又 二叉树上分支总数 b = n1+2n2
而 b = n-1 = n0 + n1 +
n -1
29. 两类特殊的二叉树: 1
2 3
满二叉树:指的是
深度为 k 且含有 2k-1 4 5 6 7
个结点的二叉树。 8 9 10 11 12 13 14 15
完全二叉树:树 a
中所含的 n 个结 b c
点和满二叉树中编
d e f g
号为 1 至 n 的
结点一一对应。 h i j
30. l 性质 4 :
具有 n 个结点的完全二叉树的深
度 为 为 log2n +1 。
证明:
设 完全二叉树的深度为 k
则根据第二条性质得 2k-1≤ n < 2k
即 k-1 ≤ log2 n < k
因为 k 只能是整数,因此, k = log2n + 1
31. l性质 5
:
若对含 n 个结点的完全二叉树从上到下且从
左至右进行 1 至 n 的编号,则对完全二叉树
中任意一个编号为 i 的结点:
(1) 若 i=1 ,则该结点是二叉树的根,无双亲,
否则,编号为 为 i/2 的结点为其双亲结点;
(2) 若 2i>n ,则该结点无左孩子,
否则,编号为 2i 的结点为其左孩子结点;
(3) 若 2i+1>n ,则该结点无右孩子结点,
否则,编号为 2i+1 的结点为其右孩子结点。
34. 0
例如 : A
1 2
B D
4 6
C E
13
F
0 1 2 3 4 5 6 7 8 9 10 11 12 13
A B D C E F
36. 1. 二叉链表 结点结构 :
root lchild data rchild
A
∧ B ∧ D
∧ C ∧ E ∧
∧ F ∧
37. C 语言的类型描述如下 :
typedef struct BiTNode { // 结点结构
TElemType data;
struct BiTNode *lchild, *rchild;
// 左右孩子指针
} BiTNode, *BiTree;
结点结构 :
lchild data rchild
38. 2 .三叉链表 结点结构 :
root parent lchild data rchild
∧ A
∧ B ∧ D
∧ C ∧ E ∧
∧ F ∧
39. C 语言的类型描述如下 :
typedef struct TriTNode { // 结点结构
TElemType data;
struct TriTNode *lchild, *rchild;
// 左右孩子指针
struct TriTNode *parent; // 双亲指针
} TriTNode, *TriTree;
结点结构 :
parent lchild data rchild
42. 一、问题的提出
顺着某一条搜索路径巡访二叉
树
中的结点,使得每个结点均被访问一
次,而且仅被访问一次。
“ 访问”的含义可以很广,如:输出结
点的信息等。
44. 对 “ 二叉树 ” 而言,可
以有三条搜索路径:
l1 .先上后下的按层次遍历;
l2 .先左(子树)后右(子树)
的遍历;
l3 .先右(子树)后左(子树)
的遍历。
45. 二、按层次遍历二叉树
实现方法为从上层到下层,每层中
从左侧到右侧依次访问每个结点。下面我们
将给出一棵二叉树及其按层次顺序访问其中
每个结点的遍历序列。
A 按层次遍历该二叉
B E 树的序列为:
C F
A B E C F D G
D G H K
H K
48. 四、算法的递归描述
void Preorder (BiTree T,
void( *visit)(TElemType& e))
{ // 先序遍历二叉树
if (T) {
visit(T->data); // 访问结点
Preorder(T->lchild, visit); // 遍历左子树
Preorder(T->rchild, visit);// 遍历右子树
}
}
49. T
T D L R
A
A D L R D L R
B E
B DLR EDLR
C F
D G C DLR F DLR
D G
中序遍历结果 : A B C D E F G
51. void Inorder (BiTree T,
void( *visit)(TElemType& e))
{ // 中序遍历二叉树
if (T) {
Inreorder(T->lchild, visit); // 遍历左子树
visit(T->data); // 访问结点
Inreorder(T->rchild, visit);// 遍历右子树
}
}
52. T
T L D R
A
L D R A L D R
B E
B LDR LDRE
C F
D G LDR C LDR F
D G
中序遍历结果 : B D C A G F E
54. void Postorder (BiTree T,
void( *visit)(TElemType& e))
{ // 后序遍历二叉树
if (T) {
Postreorder(T->lchild, visit); // 遍历左子树
Postreorder(T->rchild, visit);// 遍历右子树
visit(T->data); // 访问结点
}
}
55. 例如 :
先序序列 :
A ABCDEFGHK
B E 中序序列 :
BDCAHGKFE
C F
后序序列 :
D G DCBHKGFEA
H K
60. 1 、输入结点值,构造二叉树
算法基本思想 :
先序 ( 或中序或后序 ) 遍历二叉树
,
读入一个字符,若读入字符为空,则
二叉树为空 , 若读入字符非空,则生
成一个结点。将算法中 “ 访问结点” 的
操作改为:生成一个结点,输入结点
61. Status CreateBiTree (BiTree &T){
scanf( &ch ) ;
if (ch ==’’ ) T=NULL;
else{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))
exit(OVERFLOW);
T->data=ch; // 生成根结点
CreateBiTree( T->lchild); // 构造左子树
CreateBiTree( T->rchild); // 构造右子树
}
return(OK);
} // CreateBiTree
62. 2 、统计二叉树中叶子结点的个数
算法基本思想 :
先序 ( 或中序或后序 ) 遍历二叉树
,在遍历过程中查找叶子结点,并计
数。
由此, 需在遍历算法中增添一个 “ 计
数 ” 的参数 ,并将算法中 “ 访问结点”
的操作改为:若是叶子,则计数器增
63. void CountLeaf (BiTree T, int& count){
if ( T ) {
if ((!T->lchild)&& (!T->rchild))
count++; // 对叶子结点计数
CountLeaf( T->lchild, count);
CountLeaf( T->rchild, count);
} // if
} // CountLeaf
64. 3 、求二叉树的深度 ( 后序遍历 )
算法基本思想 :
首先分析二叉树的深度和它的左、右
子树深度之间的关系。
从二叉树深度的定义可知,二叉树的
深度应为其左、右子树深度的最大值加
1 。由此,需先分别求得左、右子树的
深度,算法中“ 访问结点” 的操作为:求得
左、右子树深度的最大值,然后加
65. int Depth (BiTree T ){ // 返回二叉树的深度
if ( !T ) depthval = 0;
else {
depthLeft = Depth( T->lchild );
depthRight= Depth( T->rchild );
depthval = 1 + (depthLeft > depthRight ?
depthLeft : depthRight);
}
return depthval;
}
66. 6.5
线索二叉树
l 何谓线索二叉树?
l 线索链表的遍历算法
l 如何建立线索链表?
67. 一、何谓线索二叉树?
遍历二叉树的结果是,
求得结点的一个线性序列。
例如 :
A 先序序列 :
B E ABCDEFGHK
C F 中序序列 :
BDCAHGKFE
D G
后序序列 :
H K DCBHKGFEA
68. 指向该线性序列中的“ 前驱” 和
“ 后继” 的指针 ,称作“ 线索
” A B C D E F G H K
^B E^
包含 “ 线索” 的存储结
C^ 构,称作 “ 线索链表”
^D^
与其相应的二叉树,
称作 “ 线索二叉树”
71. 线索链表的结点结构
lchild LTag data RTag rchild
lta g 和 rta g 是增加的两个标志域,用来区
分结点的左、右指针域是指向其左、右孩子
的指针,还是指向其前驱或后继的线索。
0 lchild域指向结点的左孩子
LTag =
1 lchild域指向结点的前驱
0 rchild域指向结点的右孩子
RTag =
1 rchild域指向结点的后继
72. 线索链表的类型描述:
typedef enum { Link, Thread } PointerThr;
// Link==0: 指针, Thread==1: 线索
typedef struct BiThrNod {
TElemType data;
struct BiThrNode *lchild, *rchild; // 左右指针
PointerThr LTag, RTag; // 左右标志
} BiThrNode, *BiThrTree;
74. 二、线索链表的遍历算法 :
由于在线索链表中添加了遍历中得到
的 “ 前驱 ” 和 “ 后继 ” 的信息,从而简化
了遍历的算法。
for ( p = firstNode(T); p; p = Succ(p) )
Visit (p);
75. 例如 :
对中序线索化链表的遍历算法
※ 中序遍历的第一个结点 ?
左子树上处于“ 最左下 ” (没有左子树
)的结点。
※ 在中序线索化链表中结点的后继 ?
若无右子树,则为后继线索所指结点;
否则为对其右子树进行中序遍历时
访问的第一个结点。
76. void InOrderTraverse_Thr(BiThrTree T,
void (*Visit)(TElemType e)) {
p = T->lchild; // p 指向根结点
while (p != T) { // 空树或遍历结束时, p==T
while (p->LTag==Link) p = p->lchild; // 第一个结
点
Visit(p->data);
while (p->RTag==Thread && p->rchild!=T)
{ p = p->rchild; Visit(p->data); } // 访问后继结
点
p = p->rchild; // p 进至其右子树根
77. 三、如何建立线索链表?
在中序遍历过程中修改结点的
左、右指针域,以保存当前访问结
点的 “ 前驱 ” 和 “ 后继 ” 信息。遍历过
程中,附设指针 pre, 并始终保持指
针 pre 指向当前访问的、指针 p 所指
结点的前驱。
78. void InThreading(BiThrTree p) {
if (p) { // 对以 p 为根的非空二叉树进行线索
化
InThreading(p->lchild); // 左子树线索化
if (!p->lchild) // 建前驱线索
{ p->LTag = Thread; p->lchild = pre; }
if (!pre->rchild) // 建后继线索
{ pre->RTag = Thread; pre->rchild = p; }
pre = p; // 保持 pre 指向 p 的前驱
InThreading(p->rchild); // 右子树线索化
} // if
79. Status InOrderThreading(BiThrTree &Thrt,
BiThrTree T) { // 构建中序线索链表
if (!(Thrt = (BiThrTree)malloc(sizeof( BiThrNode))))
exit (OVERFLOW);
Thrt->LTag = Link; Thrt->RTag =Thread; Thrt->rchild = Thrt;
if (!T) Thrt->lchild = Thrt;
else {
Thrt->lchild = T; pre = Thrt;
InThreading(T);
pre->rchild = Thrt; pre->RTag = Thread;
Thrt->rchild = pre; }
return OK;
} // InOrderThreading
82. 一、双亲表示法 :
data parent
A 0 A -1 r=0
1 B 0 n=7
B C D 2 C 0
3 D 0
E F 4 E 2
5 F 2
G
6 G 5
83. C 语言的类型描述 :
#define MAX_TREE_SIZE 100
结点结构 : data parent
typedef struct PTNode {
Elem data;
int parent; // 双亲位置域
} PTNode;
85. 二、孩子链表表示
法: data parent firstchild
A 0 A -1
-1 1 2 3
1 B 0
B C D
2 C 0 4 5
E F 3 D 0
4 E 2 6
G r=0
5 F 2
n=7
6 G 4
86. C 语言的类型描述 :
孩子结点结构 : child next
typedef struct CTNode {
int child;
struct CTNode *next;
} *ChildPtr;
87. 双亲结点结构 data firstchild
typedef struct {
Elem data;
ChildPtr firstchild;
// 孩子链的头指针
} CTBox;
89. 三、树的二叉链表 ( 孩子 - 兄弟)存储
表示法 root
A A
B
B C D C
E F E D
A F
B
G C
G
E D
F
G
90. C 语言的类型描述 :
结点结构 : firstchild data nextsibling
typedef struct CSNode{
Elem data;
struct CSNode
*firstchild, *nextsibling;
} CSNode, *CSTree;
91. 森林和二叉树的对应关系
设森林
F = ( T1, T2, …, Tn );
T1 = (root , t11, t12, …, t1m);
二叉树
B =( LBT, Node(root), RBT );
92. 由森林转换成二叉树 的转换规则为 :
若 F = Φ ,则 B = Φ ;
否则,
由 ROOT( T1 ) 对应得到 Node(root)
由 (t11, t12, …, t1m ) 对应得到 LBT ;
由 (T2, T3,…, Tn ) 对应得到 RBT 。
93. 例如: B
B C D E C
F D
E F G
G
H H
I
I J K J
K
94. 由二叉树转换为森林的转换规则为:
若 B=Φ, 则 F=Φ;
否则,
由 Node(root) 对应得到 ROOT( T1 ) ;
由 LBT 对应得到 ( t11, t12, … , t1m) ;
由 RBT 对应得到 (T2, T3, …, Tn) 。
95. 例如: B
E C B C D
F D
E F G
G
H H
I
J I J K
K
99. 一、树的遍历
树的遍历可有三条搜索路径 :
先根 ( 次序 ) 遍
历 : 若树不空,则先访问根结点,然后
依次先根遍历各棵子树。
后根 ( 次序 ) 遍
历 : 若树不空,则先依次后根遍历各棵
子树,然后访问根结点。
按层次遍历
: 若树不空,则自上而下自左至右
访问树中每个结点。
100. 先根遍历时
顶点的访问次序:
A
ABCEFGD
后根遍历时 B C D
顶点的访问次序:
E F
BEGFCDA
层次遍历时 G
顶点的访问次序
:A B C D E F G
101. 二、森林的遍历
森林由三部分构成:
B C D
1 .森林中第一
E F G 棵树的根结点;
2 .森林中第一
H 棵树的子树森林
;
3 .森林中其它
I J K
树构成的森林。
102. 森林的遍历
1. 先序遍历 若森林不空,则
访问森林中第一棵树的根结点;
先序遍历森林中第一棵树的子树森林;
先序遍历森林中 ( 除第一棵树之外 ) 其
余树构成的森林。
即:依次从左至右对森林中的每一
棵树进行先根遍历。
103. 2.中序遍历
若森林不空,则
中序遍历森林中第一棵树的子树森林;
访问森林中第一棵树的根结点;
中序遍历森林中 ( 除第一棵树之外 ) 其
余树构成的森林。
即:依次从左至右对森林中的每一棵
树进行后根遍历。
104. 例如: 先序遍历时
顶点的访问次序:
B C D
BEFCDGHIJK
E F G
后序遍历时
H 顶点的访问次序:
I J K EFBCIJKHGD
105. 树的遍历和二叉树遍
历的对应关系 ?
树 森林 二叉树
先根遍历 先序遍历 先序遍历
后根遍历 中序遍历 中序遍历
106. 6.8 哈 夫 曼 树 与
哈 夫 曼 编 码
l 最优树 ( 哈夫曼树 )
的定义
l 如何构造最优树
l 前缀编码
109. WPL(T)= WPL(T)= WPL(T)=
7×2+5×2+ 7×3+5×3+ 7×1+5×2+
2×2+4×2 4×2+2×1 2×3+4×3
=36 =46 =35
110. 二、如何构造最优树
( 哈夫曼算法 ) 以二叉树为例:
(1) 根据给定的 n 个权值 {w1, w2,
…, wn} ,构造 n 棵二叉树的集合
F = {T1, T2, … , Tn} ,
其中每棵二叉树 Ti 中均只含一个带
权值
112. (3) 从 F 中删去这两棵树,同时加入
刚生成的新树;
(4) 重复 (2) 和 (3) 两步,直至
F 中只
含一棵树为止。这棵树便是哈夫
113. 例如 : 已知权值 W={ 5, 6, 2, 9, 7 }
5 6 2 9 7
6 9 7 7
5 2
9 7 13
5 2 6 7
114. 9 7 13
5 2 6 7
29
13 16
6 7 9 7
5 2
115. 注意
:
l ① 初始森林中的 n 棵二叉树,
每棵树有一个孤立的结点,它们既
是根,又是叶子
② n 个叶子的哈夫曼树要经过
n- 1 次合并,产生 n- 1 个新结点。
最终求得的哈夫曼树中共有 2n- 1
个结点。
③ 哈夫曼树是严格的二叉树,
116. 前缀编码
在电文传输中,需要将电文中出现的
每个字符进行二进制编码。在设计编码时
需要遵守两个原则:
( 1 )发送方传输的二进制编码,到接收方
解码后必须具有唯一性,即解码结果与发
送方发送的电文完全一样;
( 2 )发送的二进制编码尽可能地短。下面
我们介绍两种编码的方式。
117. 等长编码
这种编码方式的特点 :
每个字符的编码长度相同。
设字符集只含有 4 个字符 A , B , C , D
两位二进制表示的编码分别为 00 , 01 , 1
。若现在电文为: A B A C C D A ,
应发送二进制序列: 00010010101100 ,
长度为 14 位。当接收方接收到这段电文后,
按两位一段进行译码。
种编码的特点 :
码简单且具有唯一性,但编码长度并不是
短的。
118. 2. 不等长编码
在传送电文时,为了使其二
进制位数尽
可能地少,可以将每个字符的编码设计为不等
长
的,使用频度较高的字符分配一个相对比较短
的
编码,使用频度较低的字符分配一个比较长的
编
码。例如,可以为 A , B , C , D 四个字符
分别分配
0 , 00 , 1 , 01 ,并可将上述电文用二进制
序列:
120. 哈夫曼编码的构造方法 :
( 1 )利用字符集中每个字符的使
用
频率作为权值构造一个哈夫曼树;
( 2 )从根结点开始,为到每个叶
子
结点路径上的左分支赋予 0 ,右分
支
121. 例如:
假设有一个电文字符集中有 8 个字符,每
个字符
的使用频率分别为 {0.05,0.29,0.07,0.08,0.14,0.23,
0.03,0.11} ,现以此为例设计哈夫曼编码。
为方便计算,将所有字符的频度乘以
100 ,使
其转换成整型数值集合,得到
{ 5, 29, 7, 8, 14, 23,
3, 11} ;
122. 100
0 1
42 58
0 1 0 1
19 29
00 0 1 10 0 1
8 15
010 0 1 110 0 1
0110 0111 1110 1111
5 29 7 8 14 23 3 11
123. 哈夫曼树的存储结
构
用一个大小为 2n- 1 的向量来存储哈夫
曼树中
的结点,其存储结构为:
typedef struct { // 结点类型
int weight ; // 权值,不妨设权值
均大于零
int lchild , rchild , parent ;
// 左右孩子及双亲指针
哈夫曼编码的存储结构
}HTNode , *HuffmanTree;
124. HT 数组
求哈夫曼编码过程的实例 : Weight parent lchild rchild
0 1 2 3 4 5 6 7 1
5 9
0 0 0
W 5 29 7 8 14 23 3 11 2
29 14
0 0 0
0 1 2 3 4 5 6 7 3 7 10
0 0 0
cd 0 1 1 0 0 4 8 10
0 0 0
↑ 5 14 12
0 0 0
start 6 23 0
13 0 0
HC 7 3 9
0 0 0
1 0 1 1 0
2 1 0
8 11 11
0 0 0
9 8 0
11 1
0 7
0
3 1 1 1 0
10 15 12
0 3
0 4
0
4 1 1 1 1 19 13
0 8
0 9
0
11
5 1 1 0 29 0
14 0
5 10
0
12
6 0 0 42 15
0 6
0 0
11
7 0 1 1 1 13
14 58 0
15 2
0 12
0
8 0 1 0 100 0 13
0 14
0
15
125. 求哈夫曼编码的算法 :
void HuffmanCoding(HuffmanTree &HT,
HuffmanCode &HC, int *w,int n){
if(n<=1) return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for(p=HT+1,i=1;i<=n;++i,++p,++w) *p={*w,0,0,0}
for(;i<=m;++i,++p) *p={0,0,0,0}
for(i=n+1 ; i<=m ; i++){
SelectMin(HT , i-1 , s1 , s2) ;
HT[s1].parent=i; HT[s2].parent=i ;
HTIi].1child=s1 ;
HT[j].rchild=s2 ;
HT[i].weight=T[s1].weight+T[s2].weight ;
} // end for
126. // 从叶子到根逆向求每个字符的赫夫曼编码
HC=(Huffmancode)malloc((n+1)*sizeof(char *));
cd=(char *)malloc(n*sizeof(char *));
cd[n-1]=“0” ;
for(i=1;i<=n;i++){
start=n-1 ;
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent
if(HT[f].lchild==c cd[--start]=“0”;
else cd[--start]=“1”;
HC[i]=(char * )malloc((n-start)*sizeof(char));
strcpy(Hc[i] , &cd[start]) ;
}
free(cd);
}//Huffmancoding
127. 1. 熟练掌握二叉树的结构特性,了解
相应的证明方法。
2. 熟悉二叉树的各种存储结构的特点及
适用范围。
3. 遍历二叉树是二叉树各种操作的基础。
实现二叉树遍历的具体算法与所采用的存
储结构有关。掌握各种遍历策略的递归算
法,灵活运用遍历算法实现二叉树的其它
操作。层次遍历是按另一种搜索策略进行
的遍历。
Editor's Notes P130 算法 6.2 P130 算法 6.3 1. 输入接点值 , 构造二叉树