【题意】
给出一个二叉树的先序遍历,判断这个二叉树是不是BST或BST的对称,若是则输出“YES”以及这个树的后序遍历;若都不是则输出“NO”
【思路】
BST的中序遍历是非递减数列,BST对称的中序遍历是非递增数列,假设给的树是BST或者BST的对称,则根据先序遍历和中序遍历应该可以建立起相应二叉树,若都建立不起来则不是BST或其对称。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct node{
int num;
node *left;
node *right;
}BiNode;
vector<int> preOrder;
vector<int> inOrder;
int cnt;//计数,保证输出根节点后不输出多余空格
bool isSame(int preLeft, int preRight, int inLeft, int inRight){
vector<int> nodes[2];
for(int index=preLeft; index<=preRight; index++){
nodes[0].push_back(preOrder[index]);
}
for(int index=inLeft; index<=inRight; index++){
nodes[1].push_back(inOrder[index]);
}
sort(nodes[0].begin(),nodes[0].end());
sort(nodes[1].begin(),nodes[1].end());
if(nodes[0].size()!=nodes[1].size()){
return 0;
}
else{
int i = 0;
while(i<nodes[0].size()){
if(nodes[0][i]!=nodes[1][i]){
return false;
}
i++;
}
return true;
}
}
BiNode *buildTree(int preLeft, int preRight, int inLeft, int inRight, bool mirror){
if(!isSame(preLeft,preRight,inLeft,inRight)){
return NULL;
}
else{
BiNode *father = (BiNode *)malloc(sizeof(BiNode));
father->num = preOrder[preLeft];
int i;
for(i=inLeft; i<=inRight; i++){
if(inOrder[i]==preOrder[preLeft]){
break;
}
}
//如果是镜像,那么所有和父节点值相同的应该放在左子树
if(mirror){
while(i<inRight && inOrder[i+1]==preOrder[preLeft]){
i++;
}
}
int leftNum,rightNum;
leftNum = i-inLeft;
rightNum = inRight-i;
if(leftNum==0){
father->left = NULL;
}
else{
father->left = buildTree(preLeft+1, preLeft+leftNum, inLeft, inLeft+leftNum-1, mirror);
//左子树建立失败
if(father->left==NULL){
return NULL;
}
}
if(rightNum==0){
father->right = NULL;
}
else{
father->right = buildTree(preRight-rightNum+1, preRight, inRight-rightNum+1, inRight, mirror);
//右子树建立失败
if(father->right==NULL){
return NULL;
}
}
return father;
}
}
void postTraversal(BiNode *father){
if(father==NULL){
return;
}
else{
postTraversal(father->left);
postTraversal(father->right);
cout << father->num;
if(--cnt){
cout << " ";
}
}
}
int main(int argc, char const *argv[])
{
int n;
cin >> n;
for(int i=0; i<n; i++){
int num;
cin >> num;
preOrder.push_back(num);
}
inOrder = preOrder;
sort(inOrder.begin(),inOrder.end());
BiNode *head;
head = buildTree(0,n-1,0,n-1,0);
bool flag = true;
if(head==NULL){
reverse(inOrder.begin(),inOrder.end());
head = buildTree(0,n-1,0,n-1,1);
if(head==NULL){
flag = false;
}
}
if(flag){
cout << "YES" << endl;
//后序遍历
cnt = n;
postTraversal(head);
}
else{
cout << "NO";
}
system("pause");
return 0;
}