1.根据先序、中序求后序
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000000;
int x[maxn], z[maxn], lch[maxn] = {0}, rch[maxn] = {0};
bool readline(int* a){
string s;
if (!getline(cin, s)) return false;
stringstream ss(s);
int tmp, num = 0;
while(ss >> tmp){
a[num] = tmp;
num++;
}
return num > 0;
}
int build(int xl, int xr, int ml, int mr){//建二叉树
if (ml > mr) return 0;
int root = x[xl];
int p = ml;
while(z[p] != root) p++;
int cnt = p - ml;
//求左子树大小
lch[root] = build(xl + 1, xl + cnt, ml, p - 1);//递归建造左子树
rch[root] = build(xl + cnt + 1, xr, p + 1, mr);//递归建造右子树
return root;//返回树根
}
int post_order(int root){
if (lch[root] == 0 && rch[root] == 0) return root;//如果到了叶子结点,就退回上一步
if (lch[root])
cout << post_order(lch[root]) << ' ';//先输出左子树
if (rch[root])
cout << post_order(rch[root]) << ' ';//在输出右子树
return root;//退回上一步
}
int main(){
while(readline(x)){
readline(z);
build(0, 6, 0, 6);//建树
cout << post_order(x[0]) << endl << endl;//后序遍历
}
return 0;
}
2.根据中序、后序求先序
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000000 + 10;
int z[maxn] = {4, 2, 6, 5, 1, 7, 3}, h[maxn] = {4, 6, 5, 2, 7, 3, 1}, lch[maxn], rch[maxn];
int build(int ml, int mr, int hl, int hr){//建立二叉树
if (ml > mr) return 0;
int root = h[hr];//根节点是后序遍历的最后一个
int p = ml;
while(z[p] != root) p++;
int cnt = p - ml;
lch[root] = build(ml, p - 1, hl, hl + cnt - 1);
rch[root] = build(p + 1, mr, hl + cnt, hr - 1);
return root;
}
void x_order(int root){//先序遍历
cout << root << ' ';
if (lch[root] == 0 && rch[root] == 0) return;//叶子结点,退回上一步
if (lch[root]) x_order(lch[root]);
if (rch[root]) x_order(rch[root]);
return;
}
int main(){
build(0, 6, 0, 6);//建树
x_order(h[6]);//输出先序遍历
return 0;
}
3.根据先序、后序求中序
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000000 + 10;
int x[maxn] = {1, 2, 4, 5, 6, 3, 7}, h[maxn] = {4, 6, 5, 2, 7, 3, 1}, lch[maxn], rch[maxn];
//int x[maxn] = {1, 2, 4, 3, 5, 7, 6}, h[maxn] = {4, 2, 7, 5, 6, 3, 1}, lch[maxn], rch[maxn];
int buildtree(int xl, int xr, int hl, int hr){//建立二叉树
if (xl > xr || hl > hr) return 0;//如果越界退出
if (xl == xr) {
lch[x[xl]] = 0;
rch[x[xl]] = 0;
return x[xl];
}
int root = x[xl++];
int p = hl;
while(h[p] != x[xl]) p++;//先序遍历根头节点下一个节点就是左树根节点,直接在后序遍历中找到这个节点
int cnt = p - hl;//计算左子树的节点个数
lch[root] = buildtree(xl, xl + cnt, hl, p);
rch[root] = buildtree(xl + cnt + 1, xr, p + 1, hr - 1);
return root;
}
void in_order(int root){//中序遍历
if (lch[root]) in_order(lch[root]);
cout << root << ' ';
if (rch[root]) in_order(rch[root]);
}
void x_order(int root){//先序遍历
cout << root << ' ';
if (lch[root] == 0 && rch[root] == 0) return;//叶子结点,退回上一步
if (lch[root]) x_order(lch[root]);
if (rch[root]) x_order(rch[root]);
return;
}
int post_order(int root){//后序遍历
if (lch[root] == 0 && rch[root] == 0) return root;//如果到了叶子结点,就退回上一步
if (lch[root])
cout << post_order(lch[root]) << ' ';//先输出左子树
if (rch[root])
cout << post_order(rch[root]) << ' ';//在输出右子树
return root;//退回上一步
}
int main(){
buildtree(0, 6, 0, 6);
in_order(x[0]);
cout << endl;
return 0;
}