0
点赞
收藏
分享

微信扫一扫

数据结构与算法题目集(中文) - 7-31 笛卡尔树(25 分)

seuleyang 2022-05-23 阅读 44


题目链接:​​点击打开链接​​

题目大意:二叉排序树 + 最小堆判定。

解题思路:这个题只要分开判断这个树的 k1 是否符合二叉排序树,k2 是否符合最小堆即可。最小堆的判断就是从根节点开始,看他的左右孩子的 k2 是否都比根节点的 k2 大,如果是则继续递归,否则 flag = 0 退出循环。 

k1 的判断更简单,只要中序遍历一遍 k1 的值,看知否符合从小到大的排序即可。 

其中在找根节点的时候利用 par 数组,将有父亲节点的孩子标记,则最后那个没有标记(没有父亲的)就是根节点了。

AC 代码

#include<bits/stdc++.h>
#include<cmath>

#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;

struct node
{
int l,r,k1,k2;
}nds[1010];

int par[1010], a[1010], b[1010];
int flag, len;

void init()
{
flag=1;
len=0;
mem(par,0);
}

void jde_BST(int rt)
{
if(rt!=-1)
{
jde_BST(nds[rt].l);
a[len]=b[len]=nds[rt].k1;
len++;
jde_BST(nds[rt].r);
}
}

void jde_MinHeap(int rt)
{
if(!flag) return;

int l,r;
if(nds[rt].l!=-1)
{
l=nds[rt].l;
if(nds[rt].k2>nds[l].k2)
{
flag=0; return;
}
jde_MinHeap(l);
}

if(nds[rt].r!=-1)
{
r=nds[rt].r;
if(nds[rt].k2>nds[r].k2)
{
flag=0; return;
}
jde_MinHeap(r);
}
}

int main()
{
int n;
while(~scanf("%d",&n))
{
init();
int k1,k2,l,r;
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d",&k1,&k2,&l,&r);
nds[i].k1=k1, nds[i].k2=k2, nds[i].l=l, nds[i].r=r;
if(l!=-1) par[l]=1;
if(r!=-1) par[r]=1;
}

int rt;
for(int i=0;i<n;i++) // 找根节点
if(par[i]==0){ rt=i; break; }

jde_MinHeap(rt);
if(!flag){ puts("NO"); continue; }

jde_BST(rt);
sort(a,a+len);
for(int i=0;i<len;i++)
if(a[i]!=b[i])
{
flag=0; break;
}

puts(flag?"YES":"NO");
}

return 0;
}


举报

相关推荐

0 条评论