链接
https://pintia.cn/problem-sets/994805046380707840/problems/994805070971912192
题目
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数 N(≤1000)。随后一行给出 N 个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出 YES
,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出 NO
。
样例
输入
7
8 6 5 7 10 8 11
输出
YES
5 7 6 8 11 10 8
代码
#include <iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=1e3+5;
int in[maxn];
int inl[maxn];
int inr[maxn];
int post[maxn];
int n;
int cnt=0;
struct node{
int data;
node * lchild,* rchild;
};
//插入结点
node* finsert(node* tree,int x){
if(tree==NULL){
tree=new node;
tree->data=x;
tree->lchild=NULL;
tree->rchild=NULL;
}else if(tree->data<=x){
tree->rchild=finsert(tree->rchild,x);
}else{
tree->lchild=finsert(tree->lchild,x);
}
return tree;
}
//先序遍历
void inll(node* tree){
if(tree==NULL) return;
inl[cnt++]=tree->data;
inll(tree->lchild);
inll(tree->rchild);
}
void inrr(node* tree){
if(tree==NULL) return;
inr[cnt++]=tree->data;
inrr(tree->rchild);
inrr(tree->lchild);
}
//后序遍历
void fpostl(node *tree){
if(tree==NULL) return;
fpostl(tree->lchild);
fpostl(tree->rchild);
post[cnt++]=tree->data;
}
void fpostr(node *tree){
if(tree==NULL) return;
fpostr(tree->rchild);
fpostr(tree->lchild);
post[cnt++]=tree->data;
}
int main(){
cin>>n;
node *tree=NULL;
for(int i=0;i<n;i++){
cin>>in[i];
tree=finsert(tree,in[i]);
}
bool flag=true,flag2=true;
inll(tree);
cnt=0;
inrr(tree);
for(int i=0;i<n;i++){
if(in[i]!=inl[i]){
flag=false;
break;
}
}
for(int i=0;i<n;i++){
if(in[i]!=inr[i]){
flag2=false;
break;
}
}
if(flag){
printf("YES\n");
cnt=0;
fpostl(tree);
cout<<post[0];
for(int i=1;i<n;i++){
printf(" %d",post[i]);
}
}else if(flag2){
printf("YES\n");
cnt=0;
fpostr(tree);
cout<<post[0];
for(int i=1;i<n;i++){
printf(" %d",post[i]);
}
}else{
printf("NO");
}
return 0;
}