gplt L2-004. 这是二叉搜索树吗?(BST建立的判断)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Flynn_curry/article/details/60962558


https://www.patest.cn/contests/gplt/L2-004

题意:给你一组前序遍历的结果,看是否能建成二叉搜索树或其镜像,若是则输出后序遍历输出。


思路:如果能构成,那就是hdu3999了,先建树然后遍历。关键在于如何判断不能构成。输入的序列已经知道根,所以从根dfs,遇到比根大的就是右子树,若右子树中出现比根小的,那么不能构成二叉搜索树。

这题一度写到我崩溃,先是以为树建错,甚至怀疑过pat不能用malloc,后来看了别人的居然是check部分错了。每次check的i值必须要初始化一个值,不然错误很难找啊。这位牛很巧妙的处理了这方面,直接用i中断出来递归,而不是像我一样再弄一个变量。。


#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <iostream>

using namespace std;

typedef long long ll;
const int N = 1005;

typedef struct Tree
{
    Tree *left;
    Tree *right;
    int val;
}Tree;

int seq[N];
Tree *root;
int cnt, n, kind;

bool check1(int l, int r)//检查是否为原树
{
    if(l >= r) return true;
    int i;
    for(i = l+1; i <= r; i++)
    {
        if(seq[i]>=seq[l])
        {
            break;
        }
    }
    for(int j = i; j <= r; j++)
    {
        if(seq[j]<seq[l]) return false;
    }
    return check1(l+1, i-1)&&check1(i, r);
}

bool check2(int l, int r)
{
    if(l >= r) return true;
    int i;
    for(i = l+1; i <= r; i++)
    {
        if(seq[i]<seq[l])
        {
            break;
        }
    }
    for(int j = i; j <= r; j++)
    {
        if(seq[j]>=seq[l]) return false;
    }
    return check2(l+1, i-1)&&check2(i, r);
}

Tree *creat(int num)
{
    Tree *node = (Tree*)malloc(sizeof(Tree));
    node->left = NULL;
    node->right = NULL;
    node->val = num;
    return node;
}

Tree *insertt(Tree *node, int num)
{
    if(node == NULL)
    {
        node = creat(num);
    }
    else
    {
        if(kind == 1)//是原树
        {
            if(num < node->val) node->left = insertt(node->left, num);
            else if (num >= node->val) node->right = insertt(node->right, num);
        }
        else if(kind == 2)
        {
            if(num >= node->val) node->left = insertt(node->left, num);
            else if (num < node->val) node->right = insertt(node->right, num);
        }
    }
    return node;
}

void build(int len)
{
    root = NULL;
    cnt = 0;
    for(int i = 0; i < len; i++)
    {
        int num = seq[i];
        root = insertt(root, num);
    }
}

void postorder(Tree *cur)
{
    if(cur != NULL)
    {
        postorder(cur->left);
        postorder(cur->right);
        if(cnt==n-1) printf("%d\n", cur->val);
        else
        {
            printf("%d ", cur->val);
            cnt++;
        }
    }
}

int main()
{
   // freopen("in.txt", "r", stdin);
    while(~scanf("%d", &n))
    {
        if(n == 0)
        {
            printf("YES\n");
            continue;
        }
        for(int i = 0; i < n; i++)
            scanf("%d", &seq[i]);
        kind = 0;
        if(check1(0, n-1)) kind = 1;
        else if(check2(0, n-1)) kind = 2;
        if(kind == 0)
        {
            printf("NO\n");
            continue;
        }
        build(n);
        printf("YES\n");
        postorder(root);
    }
}


猜你喜欢

转载自blog.csdn.net/Flynn_curry/article/details/60962558