L2-004. 这是二叉搜索树吗?
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数N(<=1000)。随后一行给出N个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出“YES”,然后在下一行输出该树后序遍历的结果。数字间有1个空格,一行的首尾不得有多余空格。若答案是否,则输出“NO”。
输入样例1:7 8 6 5 7 10 8 11输出样例1:
YES 5 7 6 8 11 10 8输入样例2:
7 8 10 11 8 6 7 5输出样例2:
YES 11 8 10 7 5 6 8输入样例3:
7 8 6 8 5 10 9 11输出样例3:
NO
二叉搜索树的中序序列是递增序列,其镜像树的中序序列为递减序列,如果给定的先序序列的确是二叉搜索树的先序序列,则可根据先序序列与中序序列唯一确定二叉树,如果不能建立,则说明序列不是二叉搜索树的先序序列。
先建搜索树,若失败,再建镜像树,还失败则输出NO。
注:建镜像树的时候,注意根节点在中序序列中选择相同大小的数中最靠后的一个,因此加一个while循环即可,其他与建搜索树相同
题解:
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAX = 1010;
struct Node{
int data;
Node *left, *right;
};
int n, num = 0;
int pre[MAX], in[MAX];
bool judge = true, flag = false;
bool cmp1(int a, int b){
return a < b;
}
bool cmp2(int a, int b){
return a > b;
}
Node* create(int pl, int pr, int il, int ir){
if(pl > pr) return NULL;
Node* root = new Node;
root->data = pre[pl];
int k = -1;
for(int i = il; i <= ir; i++){
if(in[i] == pre[pl]){
k = i;
if(flag){
while(k < ir &&in[k] == in[k+1]) k++;
}
break;
}
}
if(k == -1){
judge = false;
return NULL;
}
int len = k - il;
root->left = create(pl+1, pl+len, il, k-1);
root->right = create(pl+len+1, pr, k+1, ir);
return root;
}
void postorder(Node* root){
if(root != NULL){
postorder(root->left);
postorder(root->right);
printf("%d", root->data);
if(num++ != n-1) printf(" ");
else printf("\n");
}
}
void remove(Node* root){
if(root != NULL){
remove(root->left);
remove(root->right);
delete root;
}
}
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d", &pre[i]);
in[i] = pre[i];
}
sort(in, in+n, cmp1);
Node* root = create(0, n-1, 0, n-1);
if(judge){
printf("YES\n");
postorder(root);
}else{
sort(in, in+n, cmp2);
flag = true, judge = true;
remove(root);
root = create(0, n-1, 0, n-1);
if(judge){
printf("YES\n");
postorder(root);
}else printf("NO\n");
}
return 0;
}