7-12 笛卡尔树 (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

#include<bits/stdc++.h>
using namespace std;
#define maxn 10010
struct dot{
	int k1,k2;
	int left,right;
}s1[maxn];
vector<int>v,v1;
int flag=1,vis[maxn]={0};
void judge(int root){
	if(s1[root].left!=-1){
		int left=s1[root].left;
		if(s1[root].k2>s1[left].k2){
			flag=0;return;
		}
		judge(left);
	}
	if(s1[root].right!=-1){
		int right=s1[root].right;
		if(s1[root].k2>s1[right].k2){
			flag=0;return;
		}
		judge(right);
	}
}
void dfs(int root){
	if(root==-1) return;
	dfs(s1[root].left);
	v.push_back(s1[root].k1);v1.push_back(s1[root].k1);
	dfs(s1[root].right);
}
int main()
{
	int root,n;
	cin>>n;
	for( int i=0; i<n; i++ ){
		cin>>s1[i].k1>>s1[i].k2>>s1[i].left>>s1[i].right;
		if(s1[i].left!=-1) vis[s1[i].left]=1;
		if(s1[i].right!=-1) vis[s1[i].right]=1;
	}
	for( int i=0; i<n; i++ ) if(vis[i]==0) root=i;
	judge(root);
	dfs(root);
	sort(v1.begin(),v1.end());
	for( int i=0; i<v.size(); i++ ){
		if(v[i]!=v1[i]){
			flag=0;break;
		}
	}
	if(flag) cout<<"YES\n";
	else cout<<"NO\n";
    return 0;
}
 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
项目 二叉排序树中序遍历的结果是从小到大排好序的

猜你喜欢

转载自blog.csdn.net/weixin_43323172/article/details/88897206