A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:
- The left subtree of a node contains only nodes with keys less thanthe node’s key.
- The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
- Both the left and right subtrees must also be binary search trees.
If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.
Now given a sequence of integer keys, you are supposed to tell if it is the preorder traversal sequence of a BST or the mirror image of a BST.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤1000). Then N integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, first print in a line YES if the sequence is the preorder traversal sequence of a BST or the mirror image of a BST, or NO if not. Then if the answer is YES, print in the next line the postorder traversal sequence of that tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
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
题意:
给出N个正整数来作为一棵二叉排序树的结点插入顺序,问这串序列是否是该二叉排序树的先序序列或者该二叉排序树的镜像树的先序序列。所谓镜像树是指交换二叉树所有结点的左右子树而形成的树。如果是,则输出“YES”,并输出对应的树的后序序列;否则,输出"NO"。
分析:
一开始想到的方法比较复杂…因为二叉查找树(BST)的中序遍历是有序的,所有就把输入从小到大、从大到小排序,分别得出原树和其镜像的中序遍历,在利用中序遍历和输入的先序遍历,分别得出两棵二叉树,再分别检查这两棵二叉树是否是BST,从而得出结果…
写的很是麻烦,而且最终不知道为何还是有一个测试点WA。
后来看了题解才发现,只要利用输入构建BST,然后先序遍历一次,和输入对比一下,如果不对就转成镜像树,再先序遍历一次,和输入对比,就OK了…
具体看代码吧。
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
int data;
int Left;
int Right;
}Node[10000];
vector<int> input,pre; //分别存放输入和之后得到的先序遍历
int N,index=0;
int newNode(int x) //申请新结点
{
index++;
Node[index].data=x;
Node[index].Left=-1;
Node[index].Right=-1;
return index;
}
void insert(int &root,int x) //这里一定要加&来进行引用
{ //因为当root==-1时,说明当前的root的位置就是插入的位置
if(root==-1) //那么要令当前root的父结点的Left/Right等于root,但另外记录父结点很麻烦
{ //但是用&引用就可以令root等价于上一层的Node[root].Left/Node[root].Right
root=newNode(x); //若不加引用&就无法直接改变上一层的值
return;
}
if(x<Node[root].data)
insert(Node[root].Left,x); //插入位置在左子树
else
insert(Node[root].Right,x); //插入位置在右子树
}
int creat() //构建BST
{
int root=-1; //一开始为空树,root=-1
for(int i=0;i<N;i++) //将输入一个个插入
insert(root,input[i]);
return root;
}
void mirror(int root) //得到镜像树
{
if(root==-1)
return;
swap(Node[root].Left,Node[root].Right);
mirror(Node[root].Left);
mirror(Node[root].Right);
}
void pre_order(int root) //先序遍历
{
if(root==-1)
return;
pre.push_back(Node[root].data);
pre_order(Node[root].Left);
pre_order(Node[root].Right);
}
bool start=false;
void post_order(int root) //后序遍历并打印
{
if(root==-1)
return;
post_order(Node[root].Left);
post_order(Node[root].Right);
if(start)
printf(" ");
else
start=true;
printf("%d",Node[root].data);
}
int main()
{
scanf("%d",&N);
for(int i=0;i<N;i++)
{
int t;
scanf("%d",&t);
input.push_back(t);
}
int root=creat();
pre_order(root);
if(pre==input)
{
printf("YES\n");
post_order(root);
}
else
{
mirror(root);
pre.clear(); //记得清空
pre_order(root);
if(pre==input)
{
printf("YES\n");
post_order(root);
}
else
printf("NO");
}
return 0;
}