题目
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
- 所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入
输入的第一行给出正整数 N(≤1000)。随后一行给出 N 个整数键值,其间以空格分隔。
输出
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出 YES
,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出 NO
。
思路
根据先序序列用递归判断左右子树,它的镜像树同理,递归过程中判断是否符合条件,若符合则将元素插入后序序列中,最后判断这棵树以及它的镜像树哪一个符合条件,只要有一个符合条件则输出YES以及后序序列,否则输出NO
最终代码
#include<iostream>
#include<vector>
using namespace std;
#define MIN -1e7
#define MAX 1e7
vector<int> Houxu;
bool isSearchTree(int tree[],int left,int right,int min, int max){
if(left==right){
Houxu.push_back(tree[left]);
return true;
}
int root=left;
int righttree=left+1;
while(tree[righttree]<tree[root]&&righttree<=right) righttree++;
int lefttree=left+1;
if(lefttree==righttree){
if(!(tree[root]<=tree[righttree]&&tree[righttree]<max)){
return false;
}
isSearchTree(tree,righttree,right,tree[root],MAX);
Houxu.push_back(tree[root]);
}
else if(righttree>right){
if(!(min<=tree[lefttree]&&tree[lefttree]<tree[root])){
return false;
}
isSearchTree(tree,lefttree,righttree-1,MIN,tree[root]);
Houxu.push_back(tree[root]);
}
else{
if(!(min<=tree[lefttree]&&tree[lefttree]<tree[root]&&tree[root]<=tree[righttree]&&tree[righttree]<max)){
return false;
}
isSearchTree(tree,lefttree,righttree-1,MIN,tree[root]);
isSearchTree(tree,righttree,right,tree[root],MAX);
Houxu.push_back(tree[root]);
}
}
bool isMirrorSearchTree(int tree[],int left,int right,int min, int max){
if(left==right){
Houxu.push_back(tree[left]);
return true;
}
int root=left;
int righttree=left+1;
while(tree[righttree]>=tree[root]&&righttree<=right) righttree++;
int lefttree=left+1;
if(lefttree==righttree){
if(!(min<=tree[righttree]&&tree[righttree]<tree[root])){
return false;
}
isMirrorSearchTree(tree,righttree,right,MIN,tree[root]);
Houxu.push_back(tree[root]);
}
else if(righttree>right){
if(!(tree[root]<=tree[lefttree]&&tree[lefttree]<max)){
return false;
}
isMirrorSearchTree(tree,lefttree,righttree-1,tree[root],MAX);
Houxu.push_back(tree[root]);
}
else{
if(!(min<=tree[righttree]&&tree[righttree]<tree[root]&&tree[root]<=tree[lefttree]&&tree[lefttree]<max)){
return false;
}
isMirrorSearchTree(tree,lefttree,righttree-1,tree[root],MAX);
isMirrorSearchTree(tree,righttree,right,MIN,tree[root]);
Houxu.push_back(tree[root]);
}
}
int main(){
int N,tree[1007];
cin >> N;
if(N==0){
cout << "YES" << endl;
return 0;
}
for(int i=0;i<N;i++)
cin >> tree[i];
isSearchTree(tree,0,N-1,MIN,MAX);
if(Houxu.size()==N){
cout << "YES" << endl;
for(int i=0;i<Houxu.size();i++){
cout << Houxu[i];
if(i!=Houxu.size()-1)
cout << ' ';
}
cout << endl;
return 0;
}
else
Houxu.clear();
isMirrorSearchTree(tree,0,N-1,MIN,MAX);
if(Houxu.size()==N){
cout << "YES" << endl;
for(int i=0;i<Houxu.size();i++){
cout << Houxu[i];
if(i!=Houxu.size()-1)
cout << ' ';
}
cout << endl;
return 0;
}
cout << "NO" << endl;
return 0;
}
遇过的问题
总结
有关树的问题不要忘记缺左右孩子的情况
递归函数名字仔细检查