题174.2021秋周练习-3-3 搜索树判断 (25 分)
一、题目
二、题解
本题要你判断输入的先序序列是否是某二叉搜索树或某镜像二叉搜索树先序遍历序列,首先要知道一点,若前者成立那么用那个输入的先序遍历建立的二叉搜索树(用那个输入的先序遍历建二叉搜索树时,它是会按照左小右大准则来建的)的先序遍历一定是那个输入的先序遍历,后者同理。所以我们只需建对应的二叉搜索树,然后判断那棵树先序遍历结果是否为输入就好,若不是,则再去镜像处理得到镜像树,再同理,若还是不行那就是真G了。
#include <bits/stdc++.h>
using namespace std;
int N;
vector<int> pre0,pre;
typedef struct Tnode *Position;
typedef Position BinT;
struct Tnode
{
int data;
BinT left;
BinT right;
};
BinT insertNode(BinT BST,int data)//向二叉搜索树插入节点,可用此建立初始树
{
if(!BST)//当前根节点为空时,说明插入位置找到,申请空间并放入数据
{
BST=(BinT)malloc(sizeof(struct Tnode));
BST->data=data;
BST->left=NULL;
BST->right=NULL;
}
else//当前根节点不为空,说明插入位置还未找到,则递归往对应子树去找
{
if(data<BST->data)//若插入数据要比当前节点的数据来的小则往左插
{
BST->left=insertNode(BST->left,data);
}
else//反之往右插
{
BST->right=insertNode(BST->right,data);
}
}
return BST;
}
BinT reverseTree(BinT BST)//反转BST,递归得到原二叉搜索树的镜像树
{
if(BST)
{
BST->left=reverseTree(BST->left);//对左子树翻转
BST->right=reverseTree(BST->right);//对右子树翻转
//交换当前根节点左右子树
BinT TempT;
TempT=BST->left;
BST->left=BST->right;
BST->right=TempT;
}
return BST;
}
void preOrderTraversal(BinT BT)
{
BinT T=BT;
if(!T)
{
return;
}
else
{
pre.push_back(T->data);//将对二叉搜索树先序遍历的结果存入pre当中,之后用于与输入的先序遍历pre0比对
preOrderTraversal(T->left);
preOrderTraversal(T->right);
}
}
void postOrderTraversal(BinT BT)
{
static int flag=0;
BinT T=BT;
if(!T)
{
return;
}
else
{
postOrderTraversal(T->left);
postOrderTraversal(T->right);
if(flag)
{
putchar(' ');
}
printf("%d",T->data);
flag=1;
}
}
int main()
{
BinT T1=NULL,T2=NULL;
cin>>N;
for(int i=0;i<N;i++)//根据输入的先序遍历建立原二叉搜索树
{
int data;
scanf("%d",&data);
pre0.push_back(data);
T1=insertNode(T1,data);
}
preOrderTraversal(T1);
if(pre==pre0)//若建立的二叉搜索树的先序遍历结果和输入一致,则说明输入的序列是某棵二叉搜索树先序遍历序列
{
cout<<"YES"<<endl;
postOrderTraversal(T1);
return 0;
}
T2=reverseTree(T1);//建立原二叉搜索树的镜像树
pre.clear();//注意把pre清空一下
preOrderTraversal(T2);
if(pre==pre0)//若建立的二叉搜索树的先序遍历结果和输入一致,则说明输入的序列是某镜像二叉搜索树先序遍历序列
{
cout<<"YES"<<endl;
postOrderTraversal(T2);
return 0;
}
cout<<"NO"<<endl;
}