题目链接:http://www.patest.cn/contests/ds/4-06
对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。
现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。
输入格式说明:
输入的第一行包含一个正整数N(<=1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。
输出格式说明:
输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出“YES”,否侧输出“NO”。如果判断结果是“YES”,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。
样例输入与输出:
序号 | 输入 | 输出 |
1 | 7 8 6 5 7 10 8 11 | YES 5 7 6 8 11 10 8 |
2 | 7 8 10 11 8 6 7 5 | YES 11 8 10 7 5 6 8 |
3 | 7 8 6 8 5 10 9 11 | NO |
4 | 16 100 70 60 62 68 65 69 200 150 140 160 155 300 400 500 450 | YES 65 69 68 62 60 70 140 155 160 150 450 500 400 300 200 100 |
5 | 17 85 92 100 120 110 105 88 90 50 20 30 40 35 36 32 28 15 | YES 105 110 120 100 90 88 92 36 32 35 40 28 30 15 20 50 85 |
6 | 7 8 6 7 5 10 11 9 | NO |
7 | 1 -1 | YES -1 |
代码如下:
#include <cstdio>
#include <malloc.h>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <iostream>
using namespace std;
#define LEN sizeof(Node)
const int maxn = 1017;
typedef struct Node
{
int num;
struct Node *right, *left;
} Node;
queue<int >Q1;
queue<int >Q2;
void swap(Node *&T)//交换每个节点的左右子树
{
Node *tt = NULL;
if(!T)
return ;
swap(T->left);
swap(T->right);
tt = T->left;
T->left = T->right;
T->right = tt;
}
void insert(Node * &T, int data)//建立二叉树
{
if(!T)
{
T = (Node*)malloc(LEN);
T->num = data;
T->left = T->right = NULL;
return ;
}
else
{
if(data >= T->num)
{
insert(T->right, data);
}
else
{
insert(T->left, data);
}
}
}
void Pre_order(Node * &T)//先序遍历
{
if(!T)
return ;
Q1.push(T->num);
Pre_order(T->left);
Pre_order(T->right);
}
void Later_order(Node * &T)//后续遍历
{
if(!T)
return ;
Later_order(T->left);
Later_order(T->right);
Q2.push(T->num);
}
int main()
{
int n;
int a[maxn];
int flag = 0;
Node *root = NULL;
scanf("%d",&n);
for(int i = 0; i < n; i++)
{
scanf("%d",&a[i]);
insert(root, a[i]);
}
Pre_order(root);//先序遍历
for(int i = 0; i < n; i++)
{
int tt = Q1.front();
if(a[i] != tt)//不是二叉搜索数的先序遍历
{
flag++;
while(!Q1.empty())
{
Q1.pop();
}
break;
}
Q1.pop();
}
if(flag)
{
swap(root);//交换根值,变为镜像二叉搜索树
Pre_order(root);//再次先序遍历
for(int i = 0; i < n; i++)
{
int tt = Q1.front();
if(a[i] != tt)//也不是镜像二叉树的先序遍历
{
flag++;
while(!Q1.empty())
{
Q1.pop();
}
break;
}
Q1.pop();
}
}
if(flag == 2)//不是先序遍历
{
printf("NO\n");
}
else
{
printf("YES\n");
Later_order(root);//后续遍历
for(int i = 0; i < n-1; i++)
{
int tt = Q2.front();
printf("%d ",tt);
Q2.pop();
}
printf("%d\n",Q2.front());
}
return 0;
}