#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;
}
PAT(笛卡尔树)
最新推荐文章于 2024-07-15 09:03:01 发布