原题链接:http://www.patest.cn/contests/pat-a-practise/1043
本题主要是给出线序遍历判断是否BST或者BST镜像,然后给出其后序遍历
思路:
递归地判定是否是BST,即,对于给出的树,判断是否满足前半段均小于根,后半段均不大于根。
如果是,则得到了它的两个子树,对子树分别判定是否满足上一条件。途中还把根节点压入栈中
最后递归返回后,如果发现确实全是满足,则依次弹出栈中元素,自然形成后序遍历。
注意测试两子树的过程中必须先测试右子树,再测试左子树,才能满足形成后序遍历的条件。
代码如下:
</pre><pre name="code" class="cpp">// Is it a binary Search Tree
#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
vector<int> ResultPool;
int N;
int *PreOrder;
bool isBST(int root, int end, bool isMirror){
if(end - root < 3){
if(end > root) ResultPool.push_back(root);
if(end > root + 1) ResultPool.push_back(root + 1);
return true;
}
int l = root;
int r = end;
if (isMirror) {
while(PreOrder[l + 1] >= PreOrder[root] && l < end - 1) l++;
while(PreOrder[r - 1] < PreOrder[root] && r > root + 1) r--;
}else{
while(PreOrder[l + 1] < PreOrder[root] && l < end - 1) l++;
while(PreOrder[r - 1] >= PreOrder[root] && r > root + 1) r--;
}
if (r - 1 != l) return false;
ResultPool.push_back(root);
if (isBST(r, end, isMirror) && isBST(root + 1, r, isMirror)) return true;
else return false;
}
void init(){
scanf("%d", &N);
PreOrder = new int[N];
for (int i = 0; i < N; i++) scanf("%d", PreOrder + i);
}
void printRes(){
printf("YES\n");
int s = (int)ResultPool.size();
printf("%d", PreOrder[ResultPool[s - 1]]);
for (int i = 1; i < N; i++) {
printf(" %d", PreOrder[ResultPool[s - i - 1]]);
}
}
int main(int argc, char const *argv[])
{
init();
if (isBST(0, N, false) || isBST(0, N, true)) printRes();
else printf("NO\n");
return 0;
}