对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。
现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。
输入格式:
输入的第一行包含一个正整数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 <stdio.h>
#include <stdlib.h>
typedef struct TNode{
struct TNode *Left;
struct TNode *Right;
int Data;
}*BinTree;
BinTree Insert1(BinTree BST,int Data){ //创建正序二叉搜索树(左子树键值小于右子树)
if(!BST){
BST=(BinTree)malloc(sizeof(struct TNode));
BST->Data=Data;
BST->Left=BST->Right=NULL;
}
else{
if(Data>=BST->Data){
BST->Right=Insert1(BST->Right,Data);
}
else if(Data<BST->Data){
BST->Left=Insert1(BST->Left,Data);
}
}
return BST;
}
BinTree Insert2(BinTree BST,int Data){ //创建镜像二叉搜索树(左子树键值大于右子树)
if(!BST){
BST=(BinTree)malloc(sizeof(struct TNode));
BST->Data=Data;
BST->Left=BST->Right=NULL;
}
else{
if(Data>=BST->Data){
BST->Left=Insert2(BST->Left,Data);
}
else if(Data<BST->Data){
BST->Right=Insert2(BST->Right,Data);
}
}
return BST;
}
int Pre[1100]; //记录将搜索树进行前序遍历的结果
int Count=0;
void PreOrder(BinTree BT){ //进行前序遍历并将遍历结果存放于Pre中
if(BT){
Pre[Count++]=BT->Data;
PreOrder(BT->Left);
PreOrder(BT->Right);
}
}
int blank=0; //blank协助空格输出
void PostOrder(BinTree BT){ //后续遍历输出二叉树
if(BT){
PostOrder(BT->Left);
PostOrder(BT->Right);
if(blank){
printf(" ");
}
blank=1;
printf("%d",BT->Data);
}
}
int main(){
int N;
BinTree BT1=NULL; //BT1为普通二叉搜索树,BT2为镜像二叉搜索树
BinTree BT2=NULL;
scanf("%d",&N);
int Data[N]; //存放输入的序列
for(int i=0;i<N;i++){ //创建BT1和BT2
scanf("%d",&Data[i]);
BT1=Insert1(BT1,Data[i]);
BT2=Insert2(BT2,Data[i]);
}
PreOrder(BT1); //先序遍历BT1
int i;
for(i=0;i<N;i++){ //将输入的序列与先序遍历的序列对比,看是否相同,如果i==N就相同
if(Data[i]!=Pre[i])
break;
}
Count=0; //Count置为0
PreOrder(BT2); //先序遍历BT2
int j;
for(j=0;j<N;j++){
if(Data[j]!=Pre[j])
break;
}
if(i==N){ //输入序列为普通搜索树先序遍历的序列的情况
printf("YES\n");
PostOrder(BT1); //后序输出BT1
printf("\n");
}
else if(j==N){ //输入序列为镜像搜索树先序遍历的序列的情况
printf("YES\n");
PostOrder(BT2);
printf("\n");
}
else printf("NO\n");
return 0;
}