二叉搜索树 遍历 镜像
PTA 7-28 搜索树判断 (25分)
对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。
现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
Node* left, * right;
};
int nums[1005];
int n;
bool flag = false;
using ptr = Node*;
ptr insert(ptr& root, int x) {
if (root == NULL) {
root = new Node;
root->data = x;
root->left = root->right = NULL;
}
else if (x < root->data) {
root->left = insert(root->left, x);
}
else {
root->right = insert(root->right, x);
}
return root;
}
bool judge(ptr root, int& idx, int typ) {
if (idx == n) {
return true;
}
if (root == NULL) {
return true;
}
if (root->data == nums[idx]) {
++idx;
}
else {
return false;
}
if (typ) {
return judge(root->right, idx, typ) and judge(root->left, idx, typ);
}
else {
return judge(root->left, idx, typ) and judge(root->right, idx, typ);
}
}
void traverse(ptr root, int typ) {
if (!typ) {
if (root == NULL)
return;
traverse(root->left, typ);
traverse(root->right, typ);
printf(flag ? " %d" : "%d", root->data);
flag = true;
}
else {
if (root == NULL)
return;
traverse(root->right, typ);
traverse(root->left, typ);
printf(flag ? " %d" : "%d", root->data);
flag = true;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("D:/VS CODE/C++/in.txt", "r", stdin);
freopen("D:/VS CODE/C++/out.txt", "w", stdout);
#endif
cin >> n;
ptr tree = NULL;
for (int i = 0; i < n; ++i) {
scanf("%d", &nums[i]);
insert(tree, nums[i]);
}
int i1 = 0, i2 = 0;
bool true1 = judge(tree, i1, 0), true2 = judge(tree, i2, 1);
//1为镜像,2为原树
if (true1) {
cout << "YES" << endl;
traverse(tree, 0);
}
else if(true2) {
cout << "YES" << endl;
traverse(tree, 1);
}
if (true1 == false and true2 == false) {
cout << "NO" << endl;
}
fclose(stdin);
fclose(stdout);
return 0;
}