题目连接
题目连接: PTA L2-004 这是二叉搜索树吗?.
题目
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数 N(≤1000)。随后一行给出 N 个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出 YES ,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出 NO。
输入样例 :
7
8 6 5 7 10 8 11
输出样例 :
YES
5 7 6 8 11 10 8
思路
检查
对于二叉搜索树中的任意节点而言,其左子树中的任意节点必小于该节点,其右子树中的任意节点必大于等于该节点。
根据这条性质,对于树 T 的前序遍历序列,对于其中任意一节点N1,必然有:
- 在前序遍历序列中,找到第一个大于N1的节点N2, 也就是它的右孩子,N2在前序遍历序列之后的所有节点值为节点N1的右子树,都要大于等于该节点。
- 对于其镜像则都要小于该节点
所以,我们只要递归地检查序列中的每个节点的右子树,如果其中没有比该节点小的节点,则为二叉搜索树。
建树
在序列中找到第一个比当前节点大的值,作为它的右孩子。递归建树。
代码
注意边界情况即可。
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
struct treeNode {
treeNode *left;
treeNode *right;
int val;
treeNode(int v) {
val = v;
left = NULL;
right = NULL;
}
};
class binTree {
private:
int N;
public :
binTree(int n) {
N = n;
}
binTree(){}
void postTrave(treeNode* r,vector<int> &A) {
if (r == NULL)
return;
postTrave(r->left,A);
postTrave(r->right,A);
A.push_back(r->val);
}
bool isBinSearchtree(int sta,vector<int> &preorder,int l,int r) {
if (l >= r)
return true;
bool flag = true;
int i;
// 找到右孩子(镜面左孩子)
for (i = l+1; i < r; i++) {
//非镜像情况
if (sta == 1) {
//找到第一个大于等于该节点值的节点(右孩子)
if (preorder[l] <= preorder[i]) {
break;
}
}
//镜像情况
//找到第一个小于该节点值的节点(左孩子)
else {
if (preorder[l] < preorder[l]) {
break;
}
}
}
//尝试在右子树中找到一个比它小的节点
for (int j=i; j < r;j++) {
if (sta == 1) {
if (preorder[j] < preorder[l]) {
flag = false;
}
}
else {
if (preorder[l] <= preorder[j]) {
flag = false;
}
}
}
if (flag)
return isBinSearchtree(sta, preorder, l + 1, i) && isBinSearchtree(sta, preorder, i, r);
else
return false;
}
treeNode* builtBST(int sta, vector<int> pre, int l, int r) {
if (l >= r)
return NULL;
int i;
//找到右孩子
for (i = l + 1; i < r; i++) {
if (sta == 1) {
if (pre[l] <= pre[i]) {
break;
}
}
else {
if (pre[i] < pre[l]) {
break;
}
}
}
//递归建树
treeNode* root = new treeNode(pre[l]);
root->left = builtBST(sta, pre, l + 1, i);
root->right = builtBST(sta, pre, i, r);
return root;
}
};
int main() {
int N;
cin >> N;
vector<int> pre(N, 0);
for (int i = 0; i < N; i++) {
cin >> pre[i];
}
binTree bt = binTree(N);
bool c1 = bt.isBinSearchtree(1, pre, 0, N);
bool c2 = bt.isBinSearchtree(2, pre, 0, N);
vector <int> res;
if (!(c1 || c2)) {
cout << "NO" << endl;
}
else if (c1) {
cout << "YES" << endl;
bt.postTrave(bt.builtBST(1, pre, 0, N),res);
for (int i = 0; i < N; i++) {
cout << res[i];
if (i != N - 1)
cout << ' ';
}
}
else {
cout << "YES" << endl;
bt.postTrave(bt.builtBST(2, pre, 0, N), res);
for (int i = 0; i < N; i++) {
cout << res[i];
if (i != N - 1)
cout << ' ';
}
}
return 0;
}
s