二叉树的遍历
二叉树属于子节点有序的有根树.
二叉树的遍历有三种方式:
- 前序 (pre-order)
- 中序 (in-order)
- 后续 (post-order)
这三种遍历方式都是递归定义/实现的.
如果给每个节点一个编号, 就可以得到一个节点序列.
常见的问题:
- 已知前序, 中序, 求后序.
- 已知后序, 中序, 求前序.
首先应当注意到, 无论那种遍历方式, 一棵子树中的点在节点序列中是连续的 (后者说占据节点序列中的某连续段).
这样, 我们就可以递归的来解这个问题, 以求后序为例:
用solve(l1, r1, l2, l2, L, R)
求前序在区间\([l_1, r_1]\)内, 中序在区间\([l_2, r_2]\)内, 后序在\([L, R]\)内的子树的后序遍历序列.
我们首先要确定根, 根是前序序列的第一个/后序序列的最后一个. 然后要确定左右子树的大小, 中序序列中根之前的是左子树的中序序列, 根之后的是右子树的中序序列.
因此, 只有知道了中序和其他某个序的节点序列, 才能求出第三个序的节点序列. 否则左右子树的大小不能唯一确定.
Implementation
#include <bits/stdc++.h>
using namespace std;
const int N{30};
char pre[N], in[N];
void solve(int l1, int r1, int l2, int r2){
if(l1==r1) return;
char root=pre[l1];
for(int i=l2; i<r2; i++){
if(in[i]==root){
int l_size=i-l2;
solve(l1+1, l1+1+l_size, l2, i);
solve(l1+1+l_size, r1, i+1, r2);
putchar(root);
}
}
}
int main(){
cin>>pre>>in;
int n=strlen(pre);
solve(0, n, 0, n);
puts("");
return 0;
}