一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
其左子树中所有结点的键值小于该结点的键值;
其右子树中所有结点的键值大于等于该结点的键值;
其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数 N(≤1000)。随后一行给出 N 个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出 YES ,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出 NO。
输入样例 1:
7
8 6 5 7 10 8 11
输出样例 1:
YES
5 7 6 8 11 10 8
输入样例 2:
7
8 10 11 8 6 7 5
输出样例 2:
YES
11 8 10 7 5 6 8
输入样例 3:
7
8 6 8 5 10 9 11
输出样例 3:
NO
题解:这个题目因为节点的值可以相等,如果用节点的值建树的话会有死循环,所以用节点的下标建树,然后前序遍历二叉树看等不等于输入的那个样例,如果不等于,再判断一下是否为二叉树的镜像,如果哪一种符合,就输出哪一种的后序遍历结果。
#include<iostream>
#include<algorithm>
using namespace std;
int a[10005],b[10005],b2[10005],c[10005];
int left1[10005];
int right1[10005];
int p;
int len=0,len1=0,len2=0;
void createtree(int n)//建二叉树 。
{
p=1;
for(int i=2;i<=n;i++)
{
int t=p;
while(t!=0)
{
if(a[i]<a[t])
{
if(left1[t]==0)
{
left1[t]=i;
break;
}
t=left1[t];
}
else
{
if(right1[t]==0)
{
right1[t]=i;
break;
}
t=right1[t];
}
}
}
}
void dfs(int x)//前序遍历二叉树
{
if(x!=0)
{
b[len]=x;
len++;
//cout<<x<<endl;
dfs(left1[x]);
dfs(right1[x]);
}
return ;
}
void check(int x) //判断是否为二叉搜索树的镜像
{
if(x!=0)
{
b2[len2]=x;
len2++;
//cout<<x<<endl;
check(right1[x]);
check(left1[x]);
}
return ;
}
void dfs1(int x)//二叉搜索树的后序遍历
{
if(x==0)
{
return ;
}
dfs1(left1[x]);
dfs1(right1[x]);
c[len1]=x;
len1++;
}
void dfs2(int x)//二叉搜索树镜像的后序遍历
{
if(x==0)
{
return ;
}
dfs2(right1[x]);
dfs2(left1[x]);
c[len1]=x;
len1++;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
createtree(n);
int flag=1;
dfs(1);
for(int i=1;i<=n;i++)
{
if(a[i]!=a[b[i-1]])
{
flag=0;
break;
}
}
if(flag==0)
{
flag=2;
check(1);
for(int i=1;i<=n;i++)
{
if(a[i]!=a[b2[i-1]])
{
flag=0;
break;
}
}
}
if(flag)
{
cout<<"YES"<<endl;
if(flag==1)
{
dfs1(1);
}
else
{
dfs2(1);
}
for(int i=0;i<len1-1;i++)
{
cout<<a[c[i]]<<" ";
}
cout<<a[c[len1-1]]<<endl;
}
else
cout<<"NO"<<endl;
return 0;
}
本文介绍了一种算法,用于判断给定的整数序列是否为二叉搜索树或其镜像的前序遍历结果,并输出相应的后序遍历序列。通过递归定义二叉搜索树及其镜像特性,利用节点下标构建树结构,实现前序遍历验证。
3029

被折叠的 条评论
为什么被折叠?



