PAT(笛卡尔树)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct BST{
   int key;       //笛卡尔树满足二叉搜索树性质
   int value;    //笛卡尔树满足堆性质[根总大于(大堆),或小于(小堆)子树节点) ]
   int left;    //左节点
   int right;  //右节点
}b[100];
int flag;     //用来判断其是否为笛卡尔树(1:表示是 0:表示不是)
int pre[1000];//用来找出根节点所在的下标
//judge函数用来判断其value值是否满足堆性质  
void  judge(int num)
{
    int item0,item1;
    if(!flag) {
        return;
    }
    else{
        if(b[num].left!=-1){
            item0 = b[num].left;
        if(b[item0].value<b[num].value){
             flag = 0;      
            return;    
        }
        else{
            judge(item0);
        }        
    }
    if(b[num].right!=-1){
            item1 = b[num].right;
        if(b[item1].value<b[num].value){
            flag = 0;      
            return;
        }
        else{
            judge(item1);
        }        
    }
        
  }
      
}

//全局数组s数组用来记录中序排列后(二叉搜索树的中序遍历后成大小有序排列)的结果同时ss数组备份一份
//然后再排列一下s数组,再与备份的ss数组比较判断两份是否完全一致 ;即可判断其是否为笛卡尔树。
//sum记录判断有效节点个数
int  s[100],ss[100];
int sum;  //全局变量定义后记录数组s,ss下标从0开始   
//in_order函数key值进行中序遍历后按递增排列                         
void in_order(int num){
    if(num==-1){
        return;
    }
    else{
        in_order(b[num].left);
        s[sum] = ss[sum] = b[num].key; //将key值放入两数组中
        sum++;
        in_order(b[num].right);    
    }
}

int main(int argc, char** argv) {
    memset(pre,0,sizeof(pre)); //将全局数组初始化0(不要在定义时初始化);
    int n;//输入节点个数
    printf("输入节点个数:\n");
    scanf("%d",&n);
    for(int i = 0;i<n;i++){
        scanf("%d%d%d%d",&b[i].key,&b[i].value,&b[i].left,&b[i].right);
        if(b[i].left!=-1){
            pre[b[i].left]++;
        }
        if(b[i].right!=-1){
            pre[b[i].right]++;
        }
    }
    flag = 1; //初始值置为1
    sum = 0; //初始值置为0  满足其下标从0开始
    int root; //找的根节点所在数组的下标
    for(int i = 0;i<n;i++){
        if(!pre[i]){
           root = i;
           break;
        }
    }
    judge(root);
    in_order(root);
    //递增排序数组s
    for(int i = 0;i<sum-1;i++) {
        int k;
          for(int j = 0;j<sum-1-i;j++){
              if(s[j]>s[j+1]){
                   k = s[j];
                   s[j] = s[j+1];
                   s[j+1] = k;       
            }    
        }
    }
 
    for(int i = 0;i<sum;i++){
        if(s[i]!=ss[i]){
            flag = 0;
            break;
        }
    }
    if(flag){
        puts("YES");
    }
    else{
        puts("NO");
    }
    return 0;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值