L2-004. 这是二叉搜索树吗?

一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

  • 其左子树中所有结点的键值小于该结点的键值;
  • 其右子树中所有结点的键值大于等于该结点的键值;
  • 其左右子树都是二叉搜索树。

所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

输入格式:

输入的第一行给出正整数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
这题的时间我花的比其他两题还要久很多 
主要思考的是怎么既处理二叉搜索树又同时处理其镜像在同一个函数里

后来就想到了用flag,用来表明处理的是二叉搜索树或其镜像

不过因为二叉搜索树和镜像不是对称的

一个是大于等于一个是小于

所以有时得考虑flag是1或-1的情况

有时候树只有左子树,没有右字树

这个时候mid==-1也得另行处理

#include<stdio.h>
#include<malloc.h>
struct node{
    int key;
    struct node* l;
    struct node* r;
};
int temp[1000];
int p=-1;
int judge(int a[],int l,int r,int flag){
    int i,mid=-1;
    if(l>=r)return 1;
    for(i=l+1;i<=r;i++){
        if(a[i]*flag<a[l]*flag||(flag==-1)&&a[i]==a[l]){
            mid=i;
            break;
        }
    }
    if(mid==-1)return judge(a,l+1,r,flag);
    else {
    for(i=mid+1;i<=r;i++){
        if(a[i]*flag>a[l]*flag||(flag==1)&&a[i]==a[l]){
            return 0;
        }
    }
    return judge(a,l+1,mid-1,flag)&&judge(a,mid,r,flag);
    }
}
struct node *create(struct node *T,int a[],int l,int r,int flag){
    int i,mid=-1;
    if(l>r)return NULL;
    T=(struct node*)malloc(sizeof(struct node));
    T->key=a[l];
    for(i=l+1;i<=r;i++){
        if(a[i]*flag<a[l]*flag||(flag==-1)&&a[i]==a[l]){
            mid=i;
            break;
        }
    }
    if(mid!=-1)
        T->l=create(T->l,a,l+1,mid-1,flag);
    else
        T->l=create(T->l,a,l+1,r,flag);
    if(mid!=-1)
        T->r=create(T->r,a,mid,r,flag);
    else
        T->r=create(T->r,a,r+1,r,flag);
    return T;

}
void shuchu(struct node *T){
    if(T){
        shuchu(T->l);
        shuchu(T->r);
        temp[++p]=T->key;
    }
}
int main()
{
    int i,n,a[1000];
    struct node *T;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    if(a[0]<=a[1]){
        if(judge(a,0,n-1,1)){
            printf("YES\n");
            T=create(T,a,0,n-1,1);
            shuchu(T);
            for(i=0;i<p;i++)
                printf("%d ",temp[i]);
            printf("%d\n",temp[p]);
        }
        else printf("NO\n");

    }
    else{
        if(judge(a,0,n-1,-1)){
            printf("YES\n");
            T=create(T,a,0,n-1,-1);
            shuchu(T);
            for(i=0;i<p;i++)
                printf("%d ",temp[i]);
            printf("%d\n",temp[p]);
        }
        else printf("NO\n");
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值