PAT甲级1043 Is It a Binary Search Tree (25分)|C++实现

一、题目描述

原题链接
在这里插入图片描述

Input Specification:

在这里插入图片描述

​​Output Specification:

在这里插入图片描述

Sample Input 1:

7
8 6 5 7 10 8 11

Sample Output 1:

YES
5 7 6 8 11 10 8

Sample Input 2:

7
8 10 11 8 6 7 5

Sample Output 2:

YES
11 8 10 7 5 6 8

Sample Input 3:

7
8 6 8 5 10 9 11

Sample Output 3:

NO

二、解题思路

这道题是让我们判断给出的数据是不是一棵二叉搜索树或镜像二叉搜索树的先序遍历,如果是,则输出其后序遍历。我们用数组pre来存放输入的数据,并且按顺序插入到一棵二叉搜索树中,随后,我们判断一下pre的数据符不符合这两种树先序遍历的规律,也即第二个遍历的数一定小于/大于第一个数,最后一个遍历的数一定大于等于/小于第一个数。对于不同的情况,我们使用不同的遍历方法,得到一棵正常的BST的先序遍历,然后和pre数组的各个数进行比较,如果是一致的,则进行后序遍历。注意,我们是正常建立的一棵BST,所以如果题目给出的是镜像树,我们的后序遍历的左右子树遍历顺序需要做一些小调整。

三、AC代码

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int pre[1010];  //存放输入数据
vector<int> ans, result;    //存放正常BST的先序遍历,后序遍历
struct Node
{
    int key;    //值
    Node *lchild, *rchild;  //左右孩子
};
void pre1(Node* root)   //对于正常BST的先序遍历
{
    if(root == NULL)    return;
    ans.push_back(root->key);
    pre1(root->lchild);
    pre1(root->rchild);
}
void pre2(Node* root)   //对镜像BST的先序遍历
{
    if(root == NULL)    return;
    ans.push_back(root->key);
    pre2(root->rchild);
    pre2(root->lchild);
}
void postOrder1(Node* root) //对正常BST的后序遍历
{
    if(root == NULL)    return;
    postOrder1(root->lchild);
    postOrder1(root->rchild);
    result.push_back(root->key);
}
void postOrder2(Node* root) //对镜像BST的后序遍历
{
    if(root == NULL)    return;
    postOrder2(root->rchild);
    postOrder2(root->lchild);
    result.push_back(root->key);
}
void Insert(Node* &root, int x) //树的插入
{
    if(root == NULL)
    {
        root = new Node();
        root->key = x;
        root->lchild = NULL;
        root->rchild = NULL;
        return;
    }
    if(x < root->key)    Insert(root->lchild, x);
    if(x >= root->key)  Insert(root->rchild, x);
    return;
}
int main()
{
    int N;
    scanf("%d", &N);
    bool isMir = true, isOrdin = true;  //标志是正常的BST还是镜像BST
    Node *root = NULL;
    for(int i=1; i<=N; i++)
    {
        scanf("%d", &pre[i]);
        Insert(root, pre[i]);
    }
    if(N == 1)  //特判只有一个点的情况
    {
        printf("YES\n%d", pre[1]);
        return 0;
    }
    else
    {
        if(pre[2] < pre[1] && pre[N] >= pre[1]) isMir = false;  //如果题目的第二个数据比第一个数据小而且最后一个遍历的数据大于第一个,那么这棵树一定不是镜像树
        else if(pre[2] >= pre[1] && pre[N] < pre[1]) isOrdin = false;   //如果第二个遍历到的数据大于或等于第一个数据而且最后一个遍历的数据比第一个小,那么这棵树一定不是正常的BST
        else isMir = false;
    }
    isOrdin ? pre1(root) : pre2(root);  //将正常的先序遍历数据存入ans
    bool flag = true;
    for(int i=0; i<=ans.size(); i++)    //判断ans是否与题目给的数据一致
    {
        if(ans[i] != pre[i+1])
        {
            flag = false;
            break;
        }
    }
    flag ? printf("YES\n") : printf("NO\n");    //一致则输出YES,否则输出NO
    if(flag)
    {
        isOrdin ? postOrder1(root) : postOrder2(root);  //决定该按照哪种后序遍历
        for(int i=0; i<result.size(); i++)  i == 0 ? printf("%d", result[i]) : printf(" %d", result[i]);    //输出
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值