对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。
现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。
输入格式:
输入的第一行包含一个正整数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<iostream>
#include<malloc.h>
using namespace std;
struct Node {
int data;
struct Node* lchild;
struct Node* rchild;
};
bool flag = true;//控制最后不打印空格
bool flag1 = true;//是否为二叉搜索树的标志
bool flag2 = true;//是否为二叉镜像搜索树的标志
//检查是否为二叉搜索树,若是则生成相应的二叉树
Node* IsBinSearchTree(int num[], int n)
{
if (!n)
return nullptr;
int i;//保存右子树第一个数的下标
Node* temp = (Node*)malloc(sizeof(struct Node));
temp->data = num[0];
for (i = 1; i < n; i++)
{ //寻找右子树
if (num[0] <= num[i])
{
break;
}
}
for (int j = i; j < n; j++)
{
if (num[0] > num[j])
{
flag1 = false;
return nullptr;
}
}
temp->lchild = IsBinSearchTree(num + 1, i - 1);//生成左子树
temp->rchild = IsBinSearchTree(num + i, n - i);//生成右子树
return temp;
}
Node* IsBinMirror(int num[], int n)
{
if (!n)
return nullptr;
int i;//保存右子树第一个数的下标
Node* temp = (Node*)malloc(sizeof(struct Node));
temp->data = num[0];
for (i = 1; i < n; i++)
{//寻找右子树
if (num[0] > num[i])
{
break;
}
}
for (int j = i; j < n; j++)
{
if (num[0] <= num[j])
{
flag2 = false;
return nullptr;
}
}
temp->lchild = IsBinMirror(num + 1, i - 1);
temp->rchild = IsBinMirror(num + i, n - i);
return temp;
}
//后序打印输出树
void printTree(Node* tree)
{
if (tree)
{//存在空指针,当出现空指针时不打印
printTree(tree->lchild);
printTree(tree->rchild);
if (flag)flag = false;
else cout << ' ';
cout << tree->data;
}
}
int main()
{
int n;
cin >> n;
int num[1005];
for (int i = 0; i < n; i++)
{
cin >> num[i];
}
Node *tree1, *tree2;
tree1 = IsBinSearchTree(num, n);
tree2 = IsBinMirror(num, n);
if (flag1 && tree1)
{
cout << "YES\n";
printTree(tree1);
cout << endl;
}
else if (flag2 && tree2)
{
cout << "YES\n";
printTree(tree2);
cout << endl;
}
else
{
cout << "NO\n";
}
return 0;
}