一、题目描述
Input Specification:
Output Specification:
Sample Input 1:
7
8 6 5 7 10 8 11
Sample Output 1:
YES
5 7 6 8 11 10 8
Sample Input 2:
7
8 10 11 8 6 7 5
Sample Output 2:
YES
11 8 10 7 5 6 8
Sample Input 3:
7
8 6 8 5 10 9 11
Sample Output 3:
NO
二、解题思路
这道题是让我们判断给出的数据是不是一棵二叉搜索树或镜像二叉搜索树的先序遍历,如果是,则输出其后序遍历。我们用数组pre来存放输入的数据,并且按顺序插入到一棵二叉搜索树中,随后,我们判断一下pre的数据符不符合这两种树先序遍历的规律,也即第二个遍历的数一定小于/大于第一个数,最后一个遍历的数一定大于等于/小于第一个数。对于不同的情况,我们使用不同的遍历方法,得到一棵正常的BST的先序遍历,然后和pre数组的各个数进行比较,如果是一致的,则进行后序遍历。注意,我们是正常建立的一棵BST,所以如果题目给出的是镜像树,我们的后序遍历的左右子树遍历顺序需要做一些小调整。
三、AC代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int pre[1010]; //存放输入数据
vector<int> ans, result; //存放正常BST的先序遍历,后序遍历
struct Node
{
int key; //值
Node *lchild, *rchild; //左右孩子
};
void pre1(Node* root) //对于正常BST的先序遍历
{
if(root == NULL) return;
ans.push_back(root->key);
pre1(root->lchild);
pre1(root->rchild);
}
void pre2(Node* root) //对镜像BST的先序遍历
{
if(root == NULL) return;
ans.push_back(root->key);
pre2(root->rchild);
pre2(root->lchild);
}
void postOrder1(Node* root) //对正常BST的后序遍历
{
if(root == NULL) return;
postOrder1(root->lchild);
postOrder1(root->rchild);
result.push_back(root->key);
}
void postOrder2(Node* root) //对镜像BST的后序遍历
{
if(root == NULL) return;
postOrder2(root->rchild);
postOrder2(root->lchild);
result.push_back(root->key);
}
void Insert(Node* &root, int x) //树的插入
{
if(root == NULL)
{
root = new Node();
root->key = x;
root->lchild = NULL;
root->rchild = NULL;
return;
}
if(x < root->key) Insert(root->lchild, x);
if(x >= root->key) Insert(root->rchild, x);
return;
}
int main()
{
int N;
scanf("%d", &N);
bool isMir = true, isOrdin = true; //标志是正常的BST还是镜像BST
Node *root = NULL;
for(int i=1; i<=N; i++)
{
scanf("%d", &pre[i]);
Insert(root, pre[i]);
}
if(N == 1) //特判只有一个点的情况
{
printf("YES\n%d", pre[1]);
return 0;
}
else
{
if(pre[2] < pre[1] && pre[N] >= pre[1]) isMir = false; //如果题目的第二个数据比第一个数据小而且最后一个遍历的数据大于第一个,那么这棵树一定不是镜像树
else if(pre[2] >= pre[1] && pre[N] < pre[1]) isOrdin = false; //如果第二个遍历到的数据大于或等于第一个数据而且最后一个遍历的数据比第一个小,那么这棵树一定不是正常的BST
else isMir = false;
}
isOrdin ? pre1(root) : pre2(root); //将正常的先序遍历数据存入ans
bool flag = true;
for(int i=0; i<=ans.size(); i++) //判断ans是否与题目给的数据一致
{
if(ans[i] != pre[i+1])
{
flag = false;
break;
}
}
flag ? printf("YES\n") : printf("NO\n"); //一致则输出YES,否则输出NO
if(flag)
{
isOrdin ? postOrder1(root) : postOrder2(root); //决定该按照哪种后序遍历
for(int i=0; i<result.size(); i++) i == 0 ? printf("%d", result[i]) : printf(" %d", result[i]); //输出
}
return 0;
}