前中后序遍历的相互转化(附代码)
1.理论部分
首先简单的回顾一下前中后序遍历:
- 前序遍历:根➡️左➡️右
- 中序遍历:左➡️根➡️右
- 后序遍历:左➡️右➡️根
三种遍历的转化规则:
- ✔️ 已知前序遍历序列和中序遍历序列时,可以确定后序遍历序列
- ✔️ 已知后序遍历序列和中序遍历序列时,可以确定前序遍历序列
- ❌ 已知前序遍历序列和后序遍历序列时,中序遍历序列不一定
2.前序+中序 ➡️ 后序
算法题链接
已知中序遍历和前序遍历序列为:
ABEDFCHG
CBADEFGH
大致思路:从左到右遍历前序遍历序列
,可以依次得到根节点,然后在中序遍历序列
中找到该节点,则该节点左边的都是左子树上的节点,右边的都是右子树上的节点,然后继续递归遍历左子树和右子树即可。
代码如下:
#include<iostream>
#include<string.h>
using namespace std;
#define N 1100
char preOrd[N], inOrd[N];
void postOrd(int root, int l, int r){
if(l > r) return;
int newRoot = l;
while(newRoot <= r && inOrd[newRoot] != preOrd[root])
newRoot++;
postOrd(root + 1, l, newRoot - 1);
postOrd(root + 1 + newRoot - l, newRoot + 1, r);
cout<<preOrd[root];
}
int main(){
cin>>inOrd>>preOrd;
int length = strlen(preOrd);
postOrd(0, 0, length - 1);
return 0;
}
3.后序+中序 ➡️ 前序
算法题链接
思路同上,左右子树反过来就可以了😃
代码如下:
#include<iostream>
#include<string.h>
using namespace std;
#define N 1100
char postOrd[N], inOrd[N];
void preOrd(int root, int l, int r){
if(l > r) return;
cout<<postOrd[root];
int newRoot = l;
while(newRoot <= r && inOrd[newRoot] != postOrd[root])
newRoot++;
preOrd(root - 1 - r + newRoot, l, newRoot - 1);
preOrd(root - 1, newRoot + 1, r);
}
int main(){
cin>>inOrd>>postOrd;
int length = strlen(inOrd);
preOrd(length - 1, 0, length - 1);
return 0;
}