基础实验4-2.4 搜索树判断 (25point(s))

PTA基础实验4-2.4 搜索树判断 (25point(s))

题意

  • 给出一棵树的前序遍历或者镜像的前序遍历,判断是否是二叉树,如果是,输出后序遍历。

题解

  • 如果是一棵二叉树,那么通过前序+中序可以构建,中序升序排列。
  • 最后判断二叉树是否完整以及叶子的大小是否符合规则
  • 对于镜像,中序是降序。用同样的方式实现。

代码

#include <bits/stdc++.h>
using namespace std;
int const N = 1000 + 10;
int pre[N],post[N],in[N],n,pos,id;
vector<int>ans;
struct Node{
    int left,right;
    int val;
}node[N];
int dfs(int l,int r){   //pos表示pre的位置
    if(l > r)   return -1;
    int mid = -1;
    for(int i=l;i<=r;i++){
        if(pre[pos] == in[i]){
            mid = i;
            break;
        }
    }
    if(mid == -1)   return -1;  //来判断是否可以成树
    int tid = id++;
    node[tid].val = pre[pos++];
    node[tid].left = dfs(l,mid - 1);
    node[tid].right = dfs(mid + 1,r);
    ans.push_back(node[tid].val);
    return tid;
}
int mdfs(int l,int r){   //pos表示pre的位置
    if(l > r)   return -1;
    int mid = -1;
    for(int i=l;i<=r;i++){
        if(pre[pos] == in[i]){    //这里不用break
            mid = i;
        }
    }
    if(mid == -1)   return -1;
    int tid = id++;
    node[tid].val = pre[pos++];
    node[tid].left = dfs(l,mid - 1);
    node[tid].right = dfs(mid + 1,r);
    ans.push_back(node[tid].val);
    return tid;
}
bool judge(int root){
    int l = node[root].left,    r = node[root].right;
    if(l != -1 && node[l].val > node[root].val)  return false;
    if(r != -1 && node[r].val <= node[root].val) return false;
    if(l != -1 && !judge(l)) return false;
    if(r != -1 && !judge(r)) return false; 
    return true;
}
bool mjudge(int root){
    int l = node[root].left,    r = node[root].right;
    if(l != -1 && node[l].val < node[root].val)  return false;
    if(r != -1 && node[r].val >= node[root].val) return false;
    if(l != -1 && !mjudge(l)) return false;
    if(r != -1 && !mjudge(r)) return false; 
    return true;
}
bool solve1(){
    sort(in + 1,in + 1 + n);
    id = pos = 1;
    dfs(1,n);   //由pre+in构造二叉树
    if(judge(1) && ans.size() == n){    //ans.size() == n表示后序遍历完整
        printf("YES\n");
        for(int i=0;i<ans.size();i++){
            printf("%d%c",ans[i],i == ans.size() - 1 ? '\n' : ' ');
        }
        return true;
    }
    return false;
}
bool solve2(){
    reverse(in + 1,in + 1 + n); //镜像的中序遍历大小变换
    id = pos = 1;
    ans.clear();
    mdfs(1,n);
    if(mjudge(1) && ans.size() == n){
        printf("YES\n");
        for(int i=0;i<ans.size();i++){
            printf("%d%c",ans[i],i == ans.size() - 1 ? '\n' : ' ');
        }
        return true;
    }
    return false;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&pre[i]);
        in[i] = pre[i];
    }
    if(!solve1()){
        if(!solve2())
            printf("NO\n");
    }
    return 0;
}

 

posted @ 2020-04-27 13:21  月光下の魔术师  阅读(30)  评论(0)    收藏  举报