zoukankan      html  css  js  c++  java
  • PTA 笛卡尔树

    笛卡尔树 (25 分)

    笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小。给定一棵二叉树,请判断该树是否笛卡尔树。

    输入格式:

    输入首先给出正整数N(≤1000),为树中结点的个数。随后N行,每行给出一个结点的信息,包括:结点的K1值、K2值、左孩子结点编号、右孩子结点编号。设结点从0~(N-1)顺序编号。若某结点不存在孩子结点,则该位置给出1。

    输出格式:

    输出YES如果该树是一棵笛卡尔树;否则输出NO

    输入样例1:

    6
    8 27 5 1
    9 40 -1 -1
    10 20 0 3
    12 21 -1 4
    15 22 -1 -1
    5 35 -1 -1

    输出样例1:

    YES

    输入样例2:

    6
    8 27 5 1
    9 40 -1 -1
    10 20 0 3
    12 11 -1 4
    15 22 -1 -1
    50 35 -1 -1

    输出样例2:

    NO

    笛卡尔树的性质:

    1.如果只含key值,不含value值的话,此树就像是一颗二叉搜索树。性质和二叉搜索树的性质是一样的,从左子树到右子树依次变大。而val值的意思正好和key值的意思相反。

    2.笛卡尔树的以key值为准,中序遍历出的key值必须是从小到大的(不能相等)。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    
    using namespace std;
    
    struct node
    {
        int key;
        int val;
        int lchild;
        int rchild;
    }a[1005];
    
    int vis[1005],flag,ans[1005],cnt=0;
    
    void fun(int root)
    {
        if(!flag)        //减少不必要的递归,节约时间
            return ;
        if(a[root].lchild!=-1)    //如果左孩子不为-1,则进行下一步操作
        {
            int left=a[root].lchild;
            if(a[left].key>=a[root].key)    //假如该位置的前一个左孩子大于或者等于该位置的key值                            //
            {                                //则将flag赋值为flase
                flag=0;
                return ;
            }
            fun(left);
        }
        if(a[root].rchild!=-1)        //同上,就是该位置的前一个右孩子小于或者等于该位置的val值
        {
            int right=a[root].rchild;
            if(a[right].val<=a[root].val)
            {
                flag=0;
                return ;
            }
            fun(right);
        }
    }
    
    void in_order(int root)//中序遍历此树
    {
        if(root!=-1)
        {
            in_order(a[root].lchild);
            ans[cnt++]=a[root].key;
            in_order(a[root].rchild);
        }
    }
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d%d",&a[i].key,&a[i].val,&a[i].lchild,&a[i].rchild);
            if(a[i].lchild!=-1)            //记录所有出现的结点,没出现的那个节点就是根节点
                vis[a[i].lchild]=1;
            if(a[i].rchild!=-1)
                vis[a[i].rchild]=1;
        }
        int root=-1;
        for(int i=0;i<n;i++)        //找出根节点
            if(!vis[i])
            {
                root=i;
                break;            //记住跳出,减少没有必要的循环
            }
        if(root==-1)         //判断此树是否为空树
        {
            printf("YES
    ");
            return 0;
        }
        flag=1;                //如果为true则是笛卡尔树,否则不是
        fun(root);        //递归判断此树
        in_order(root);        //中序遍历
        for(int i=0;i<cnt-1;i++)    //判断中序遍历出的key值是否符合二叉搜索树的性质(从小到大)
            if(ans[i]>=ans[i+1])
            {
                flag=0;
                break;
            }
        if(flag)
            printf("YES
    ");
        else
            printf("NO
    ");
        return 0;
    }
  • 相关阅读:
    2018-2019-1 20175330 《信息安全系统设计基础》第四周学习总结
    2019-2020-1 20175330 《信息安全系统设计基础》第三周学习总结
    《程序设计与数据结构》实验一报告
    《程序设计与数据结构》第四周学习总结
    学号 20172326 《程序设计与数据结构》第三周学习总结
    《程序设计与数据结构》第二周学习总结
    《JAVA软件结构与数据结构》第一周学习总结
    《程序设计与数据结构》(上)课程总结
    2017-2018-2 《程序设计与数据结构》实验五报告
    《程序设计与数据结构》实验四报告
  • 原文地址:https://www.cnblogs.com/buhuiflydepig/p/10610671.html
Copyright © 2011-2022 走看看