树的遍历
- 先根遍历
- 后根遍历
- 层序遍历
- 树的先根遍历
若树非空,先访问根结点,再依次对每棵子树进行先根遍历。
//树的先根遍历
void PreOrder(TreeNode *R){
if(R!=NULL){
visit(R); //访问根结点
while(R还有下一个子树T)
PreOrder(T); //先根遍历下一棵子树
}
}
先根遍历序列:ABEKFCGDHIJ
用“孩子兄弟表示法”将该树转换为二叉树,得到下图:
结论:树的先根遍历序列,与这棵树对应的二叉树先序遍历序列相同。
- 树的后根遍历
若树非空,现依次对每棵子树进行后根遍历,最后再访问根结点。
//树的后根遍历
void PostOrder(TreeNode *R){
if(R!=NULL){
while(R还有下一个子树)
PostOrder(T); //后根遍历下一棵子树
visit(R); //访问根结点
}
}
后根遍历序列:KEFBGCHIJDA(K是第一个被访问的结点,最后回到A)
结论:树的后根遍历序列,与这棵树对应的二叉树的中序遍历序列相同。
- 树的层次遍历(用队列实现)
1、若树非空,则根结点入队
2、若队列非空,队头元素出队并访问,同时将该元素的孩子依次入队
3、重复②直到队列为空
入队 队内 出队(访问)
A A A
BCD BCD B
EF CDEF C
G DEFG D
HIJ EFGHIJ E
K FGHIJK F
GHIJK G
HIJK H
IJK I
JK J
K K
树的层次遍历==广度优先遍历
树的先根遍历、后根遍历==深度优先遍历
森林的遍历
- 先序遍历
- 中序遍历
- 森林的先序遍历
若森林非空,则按如下规则进行遍历:
1、访问森林中第一棵树的根结点。
2、先序遍历弟弟一棵树中根结点的子树森林。
3、先序遍历除去第一棵树之后剩余的树构成森立。
先序遍历序列:BEKLFCGDHMIJ
森林的先序遍历,效果等同于,依次对各个树进行先根遍历。
同样,效果等同于,对森林转换成的二叉树进行先序遍历。
- 森林的中序遍历
若森林非空,则按如下规则进行遍历:
1、中序遍历森林中第一棵树的根结点的子树森林。
2、访问第一棵树的根结点。
3、中序遍历除去第一棵树之后剩余的树构成的森林。
中序遍历序列:KLEFBGCMHIJD
森林的中序遍历,效果等同于,依次对各个树进行后根遍历。
同样,效果等同于,对森林转换成的二叉树进行中序遍历。
总结:
树 | 森林 | 二叉树 |
---|---|---|
先根遍历 | 先序遍历 | 先序遍历 |
后根遍历 | 中序遍历 | 中序遍历 |