《二叉树遍历》PPT课件
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6.3 二叉树的遍历
a
1
一、问题的提出
二、先左后右的遍历算法
三、算法的递归描述
四、中序遍历算法的非递归描述
五、遍历算法的应用举例
a
2
一、问题的提出
顺着某一条搜索路径巡访二叉树 中的结点,使得每个结点均被访问一
次,而且仅被访问一次。
“访问”的含义可以很广,如:输出结 点的信息等。
a
3
“遍历”是任何类型均有的操作,
a
5
二、先左后右的遍历算法
先(根)序的遍历算法 中(根)序的遍历算法 后(根)序的遍历算法
a
6
先(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。
a
7
中(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)中序遍历左子树; (2)访问根结点; (3)中序遍历右子树。
对线性结构而言,只有一条搜索路
径(因为每个结点均只有一个后继),
故不需要另加讨论。而二叉树是非
线性结构, 每个结点有两个后继,
则存在如何遍历即按什么样的搜索
路径遍历的问题。
a
4
对“二叉树”而言,可以有 三条搜索路径:
1.先上后下的按层次遍历;
2.先左(子树)后右(子树) 的遍历;
3.先右(子树)后左(子树) 的遍历。
a
^e f^
^g ^ 26
思考: 已知中序遍历:B D C E A F H G 已知后序遍历:D E C B H G F A
A
B
F
C
G
(B D C E)D E H
a
27
作业:
1.写出中序遍历二叉树的递归算法 2.写出计算二叉树叶结点个数的递归算法
叶结点满足的条件 3.给定二叉树的两种遍历序列,分别是:
将根结点设置为待入栈结点p 如果p不为空,则p入栈,将p的左孩子设置 为待入栈结点 如果p为空,则栈顶元素出栈,访问栈顶元 素,然后将栈顶元素的右孩子设置为待入 栈结点 直到P为空且栈为空结束 算法见书上6.3
a
17
五、遍历算法的应用举例
1、求二叉树的深度(后序遍历) 2、建立二叉树的存储结构
a
18
先序:访问左子树之前访问根 中序:访问右子树之前访问根 后序:访问右子树之后访问根
a
13
A
B
D
C
F
E
H
I
a
14
四、用堆栈实现二叉树中序遍历
A
B
F
DCE H
I
a
15
A
B
F
DCE H
I
A
B
B
A
A
D
D B A
^
D B A
^
C
^
^
F
E
B
C
A
A
C A
E
AF
F
I
ቤተ መጻሕፍቲ ባይዱ
^
^
^
H
^
^
I
I
E
E
E
F
F
F
FH
H
a
16
用堆栈实现二叉树中序遍历的规 律
1、求二叉树的深度(后序遍历) 算法基本思想:
首先分析二叉树的深度和它的左、右子树 深度之间的关系。
从二叉树深度的定义可知,二叉树的深度应为其 左、右子树深度的最大值加1。由此,需先分别求得 左、右子树的深度,算法中“访问结点”的操作为: 求得左、右子树深度的最大值,然后加 1 。
a
19
int Depth (BiTree T ){ // 返回二叉树的深度
} BiTNode, *BiTree;
结点结构: lchild data rchild
a
10
先(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。
a
11
三、算法的递归描述
Status Preorder (BiTree T,
void( *visit)(TElemType& e)) { // 先序遍历二叉树
exit(OVERFLOW);
T->data = ch;
// 生成根结点
CreateBiTree(T->lchild); // 构造左子树
CreateBiTree(T->rchild); // 构造右子树
}
return OK; } // CreateBa iTree
24
由二叉树的先序和中序序列建树
a
8
后(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)后序遍历左子树; (2)后序遍历右子树; (3)访问根结点。
a
9
二叉树C 语言的类型描述如下:
typedef struct BiTNode { // 结点结构 TElemType data; struct BiTNode *lchild, *rchild; // 左右孩子指针
C
a
22
基本的构造过程举例如下:
AB C D
T
A
^B
^D^
^C^
a
23
Status CreateBiTree(BiTree &T) {
scanf(&ch);
if (ch==' ') T = NULL;
else {
if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))
if (T) { visit(T->data);
// 访问结点
Preorder(T->lchild, visit); // 遍历左子树
Preorder(T->rchild, visit);// 遍历右子树
}
}
a
12
说明
访问函数的示例和preOrder函数调用的方法算 法6.1所示.
同理可以实现中序遍历二叉树和后序遍历二叉 树. 3种遍历思想一致,不同之处在于访问根结点的 时机
}
return depthval;
}
a
20
2、建立二叉树的存储 结构
不同的定义方法相应有不同的 存储结构的建立算法
a
21
以字符串的形式 根 左子树 右子树 定义一棵二叉树
例如: 空树
以空白字符“ ”表示
只含一个根结点 以字符串“A ”表示
的二叉树 A
A
以下列字符串表示
B
D A(B( ,C( , )),D( , ))
仅知二叉树的先序序列“abcdefg”
不能唯一确定一棵二叉树,
如果同时已知二叉树的中序序列
“cbdaegf”,则会如何?
二叉树的先序序列 根 左子树 右子树
二叉树的中序序列 左子树 根 右子树
a
25
例如: a b c d e f g 先序序列
c b d a e g f 中序序列
a b
^c ^ ^d ^
前序遍历序列:D,A,C,E,B,H,F,G, I; 中序遍历序列:D,C,B,E,H,A,G, I,F,试画出二叉树,并写出该二叉树的前序 遍历序列和中序遍历序列。
if ( !T ) depthval = 0;
else {
depthLeft = Depth( T->lchild );
depthRight= Depth( T->rchild );
depthval = 1 + (depthLeft > depthRight ?
depthLeft : depthRight);
a
1
一、问题的提出
二、先左后右的遍历算法
三、算法的递归描述
四、中序遍历算法的非递归描述
五、遍历算法的应用举例
a
2
一、问题的提出
顺着某一条搜索路径巡访二叉树 中的结点,使得每个结点均被访问一
次,而且仅被访问一次。
“访问”的含义可以很广,如:输出结 点的信息等。
a
3
“遍历”是任何类型均有的操作,
a
5
二、先左后右的遍历算法
先(根)序的遍历算法 中(根)序的遍历算法 后(根)序的遍历算法
a
6
先(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。
a
7
中(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)中序遍历左子树; (2)访问根结点; (3)中序遍历右子树。
对线性结构而言,只有一条搜索路
径(因为每个结点均只有一个后继),
故不需要另加讨论。而二叉树是非
线性结构, 每个结点有两个后继,
则存在如何遍历即按什么样的搜索
路径遍历的问题。
a
4
对“二叉树”而言,可以有 三条搜索路径:
1.先上后下的按层次遍历;
2.先左(子树)后右(子树) 的遍历;
3.先右(子树)后左(子树) 的遍历。
a
^e f^
^g ^ 26
思考: 已知中序遍历:B D C E A F H G 已知后序遍历:D E C B H G F A
A
B
F
C
G
(B D C E)D E H
a
27
作业:
1.写出中序遍历二叉树的递归算法 2.写出计算二叉树叶结点个数的递归算法
叶结点满足的条件 3.给定二叉树的两种遍历序列,分别是:
将根结点设置为待入栈结点p 如果p不为空,则p入栈,将p的左孩子设置 为待入栈结点 如果p为空,则栈顶元素出栈,访问栈顶元 素,然后将栈顶元素的右孩子设置为待入 栈结点 直到P为空且栈为空结束 算法见书上6.3
a
17
五、遍历算法的应用举例
1、求二叉树的深度(后序遍历) 2、建立二叉树的存储结构
a
18
先序:访问左子树之前访问根 中序:访问右子树之前访问根 后序:访问右子树之后访问根
a
13
A
B
D
C
F
E
H
I
a
14
四、用堆栈实现二叉树中序遍历
A
B
F
DCE H
I
a
15
A
B
F
DCE H
I
A
B
B
A
A
D
D B A
^
D B A
^
C
^
^
F
E
B
C
A
A
C A
E
AF
F
I
ቤተ መጻሕፍቲ ባይዱ
^
^
^
H
^
^
I
I
E
E
E
F
F
F
FH
H
a
16
用堆栈实现二叉树中序遍历的规 律
1、求二叉树的深度(后序遍历) 算法基本思想:
首先分析二叉树的深度和它的左、右子树 深度之间的关系。
从二叉树深度的定义可知,二叉树的深度应为其 左、右子树深度的最大值加1。由此,需先分别求得 左、右子树的深度,算法中“访问结点”的操作为: 求得左、右子树深度的最大值,然后加 1 。
a
19
int Depth (BiTree T ){ // 返回二叉树的深度
} BiTNode, *BiTree;
结点结构: lchild data rchild
a
10
先(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。
a
11
三、算法的递归描述
Status Preorder (BiTree T,
void( *visit)(TElemType& e)) { // 先序遍历二叉树
exit(OVERFLOW);
T->data = ch;
// 生成根结点
CreateBiTree(T->lchild); // 构造左子树
CreateBiTree(T->rchild); // 构造右子树
}
return OK; } // CreateBa iTree
24
由二叉树的先序和中序序列建树
a
8
后(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)后序遍历左子树; (2)后序遍历右子树; (3)访问根结点。
a
9
二叉树C 语言的类型描述如下:
typedef struct BiTNode { // 结点结构 TElemType data; struct BiTNode *lchild, *rchild; // 左右孩子指针
C
a
22
基本的构造过程举例如下:
AB C D
T
A
^B
^D^
^C^
a
23
Status CreateBiTree(BiTree &T) {
scanf(&ch);
if (ch==' ') T = NULL;
else {
if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))
if (T) { visit(T->data);
// 访问结点
Preorder(T->lchild, visit); // 遍历左子树
Preorder(T->rchild, visit);// 遍历右子树
}
}
a
12
说明
访问函数的示例和preOrder函数调用的方法算 法6.1所示.
同理可以实现中序遍历二叉树和后序遍历二叉 树. 3种遍历思想一致,不同之处在于访问根结点的 时机
}
return depthval;
}
a
20
2、建立二叉树的存储 结构
不同的定义方法相应有不同的 存储结构的建立算法
a
21
以字符串的形式 根 左子树 右子树 定义一棵二叉树
例如: 空树
以空白字符“ ”表示
只含一个根结点 以字符串“A ”表示
的二叉树 A
A
以下列字符串表示
B
D A(B( ,C( , )),D( , ))
仅知二叉树的先序序列“abcdefg”
不能唯一确定一棵二叉树,
如果同时已知二叉树的中序序列
“cbdaegf”,则会如何?
二叉树的先序序列 根 左子树 右子树
二叉树的中序序列 左子树 根 右子树
a
25
例如: a b c d e f g 先序序列
c b d a e g f 中序序列
a b
^c ^ ^d ^
前序遍历序列:D,A,C,E,B,H,F,G, I; 中序遍历序列:D,C,B,E,H,A,G, I,F,试画出二叉树,并写出该二叉树的前序 遍历序列和中序遍历序列。
if ( !T ) depthval = 0;
else {
depthLeft = Depth( T->lchild );
depthRight= Depth( T->rchild );
depthval = 1 + (depthLeft > depthRight ?
depthLeft : depthRight);