题意:
给定一棵树的先序遍历,问是不是BST 或者 MirrorImage; 是的话输出后序遍历
思路:
BST 和 Mirror Image 都有一个性质,就是可以通过先序遍历把树建出来,
因为对于一个先序遍历,第一个点是当前树的根结点,①如果有两颗子树的话,那后面必然分成两段,一段值全部小于根结点的值,另一段全部大于根结点的值;②如果只有一颗子树的话,要么全大于根结点的值要么全小于根结点的值。③其余情况不满足BST 或者 Mirror Image,在本题来说就是“NO”
BST 和 Mirror Image 也有区别,在于左子树大还是右子树大,确定以后后面的子树必须按照同样的规则;规则不符也是“NO”
现在我们用type表示BST 和 Mirror Image ,分别用1,0表示;如果当前类型还不确定,那type的值为-1;
类似于先序遍历+中序遍历的递归过程,直接对整个序列递归,每次确定当前树的根结点,然后找子树的类型以及左右子树的分割点,如果中间出现不合法的情况,ok设为false;
最后遍历后序输出
更简单的一种方法:https://blog.csdn.net/xiang_6/article/details/100535762
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 7;
int n, t, id = 1, tp = -1, type = -1, cnt = 0;
int a[maxn];
bool ok = true;
struct node {
int v;
int l, r;
}tr[maxn];
int getpos(int l, int r) {
int t1, t2;
for(t1 = l+1; t1 <= r; ++t1) if(a[t1] < a[l]) break;
for(t2 = l+1; t2 <= r; ++t2) if(a[t2] > a[l]) break;
if(t1 > r) {
type = -1;
return -1;
}
else if(t2 > r) {
type = -1;
return -1;
}
else if(t1 > t2) { // Mirror Image
type = 0;
for(int i = t1; i <= r; ++i) {
if(a[i] > a[l]) { ok = false; break; }
}
for(int i = t2; i < t1; ++i) {
if(a[i] < a[l]) { ok = false; break; }
}
return t1;
}
else if(t2 > t1) { // BST
type = 1;
for(int i = t2; i <= r; ++i) {
if(a[i] < a[l]) { ok = false; break; }
}
for(int i = t1; i < t2; ++i) {
if(a[i] > a[l]) { ok = false; break; }
}
return t2;
}
}
void solve(int l, int r, int &root) {
//cout << l << " +++++++ " << r << endl;
if(l > r) return;
root = id++;
tr[root].v = a[l];
int x = getpos(l, r);
if(x == -1) {
solve(l+1, r, tr[root].l);
}
else if(type == 0){
if(!ok) return;
if(tp == 1) {
ok = false;
return;
}
else {
tp = 0;
solve(l+1, x-1, tr[root].l);
solve(x, r, tr[root].r);
}
}
else if(type == 1) {
if(!ok) return;
if(tp == 0) {
ok = false;
return;
}
else {
tp = 1;
solve(l+1, x-1, tr[root].l);
solve(x, r, tr[root].r);
}
}
}
void print(int id) {
if(!id) return;
print(tr[id].l);
print(tr[id].r);
if(cnt) {
printf(" %d", tr[id].v);
}
else {
cnt = 1;
printf("%d", tr[id].v);
}
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
solve(1, n, t);
if(!ok) {
return 0*puts("NO");
}
puts("YES");
print(1);
return 0;
}