3 搜索树判断 分数 25作者 DS课程组单位 浙江大学
搜索 判断 25 课程 单位 作者 分数 DS
2023-09-14 09:07:12 时间
对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。
现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。
输入格式:
输入的第一行包含一个正整数N(≤1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。
输出格式:
输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出YES
,否侧输出NO
。如果判断结果是YES
,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。
输入样例1:
7
8 6 5 7 10 8 11
输出样例1:
YES
5 7 6 8 11 10 8
输入样例2:
7
8 6 8 5 10 9 11
输出样例2:
NO
思路:
建立二叉搜索树,得出先序遍历序列和镜像先序遍历序列。
注意,后序遍历要分是不是镜像的后序遍历序列。
代码:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
typedef pair<int, int> PII;
typedef pair<double, double>PDD;
//
const int N = 1010;
int a[N],pre1[N], pre2[N], post1[N], post2[N];
int k,l,r,z;
struct Tree {
int e;
Tree* lchild, *rchild;
};
typedef Tree* pt;
void Create(pt& T, int x) {
T = (pt)malloc(sizeof(Tree));
T->e = x;
T->lchild = T->rchild = NULL;
}
void BuildTree(pt& T,int x) {
if (T==NULL)Create(T, x);
else {
if(x>=T->e)BuildTree(T->rchild, x);
else BuildTree(T->lchild, x);
}
}
void f1(pt T) {
if (T == NULL)return;
pre1[k++] = T->e;
f1(T->lchild);
f1(T->rchild);
}
void f2(pt T) {
if (T == NULL)return;
pre2[l++] = T->e;
f2(T->rchild);
f2(T->lchild);
}
void f3(pt T) {
if (T == NULL)return;
f3(T->lchild);
f3(T->rchild);
post1[r++]= T->e;
}
void f4(pt T) {
if (T == NULL)return;
f4(T->rchild);
f4(T->lchild);
post2[z++] = T->e;
}
int main() {
int n;
cin >> n;
pt t=NULL;
for (int i = 0; i < n; i++) {
cin >> a[i];
BuildTree(t, a[i]);
}
f1(t), f2(t), f3(t),f4(t);
bool fg1 = true,fg2 = true;
for (int i = 0; i < n; i++) if (a[i] != pre1[i])fg1 = false;
for (int i = 0; i < n; i++) if (a[i] != pre2[i])fg2 = false;
if (!fg1 && !fg2) {
cout << "NO"; return 0;
}
cout << "YES" << endl;
if (fg1) {
for (int i = 0; i < n; i++) {
if (!i)cout << post1[i];
else cout << " " << post1[i];
}
}
else {
for (int i = 0; i < n; i++) {
if (!i)cout << post2[i];
else cout << " " << post2[i];
}
}
return 0;
}