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

解法:

这道题关键是需要判断K1是否满足二叉搜索树,K2是否比其子树的K2都小。

#include<iostream>
#include<cstring>

using namespace std;
#define INT_MAX 2147483647
#define INT_MIN (-INT_MAX - 1)

struct Node {
	int k1;
	int k2;
	int lchild;
	int rchild;
}CartTree[1005];

bool flag = true;//是否是笛卡尔树的标志

void IsCartTree(int root,int min_k1,int max_k1)
{
	if (root == -1)
		return;
	int k1 = CartTree[root].k1;
	int k2 = CartTree[root].k2;
	int lchild = CartTree[root].lchild;
	int rchild = CartTree[root].rchild;
	if(k1 < min_k1||k1 > max_k1)
    {
        flag = false;
        return;
    }
	if (lchild != -1)
	{
		if ( CartTree[lchild].k2 <= k2)
		{
			flag = false;
			return;
		}
	}
	if (rchild != -1)
	{
		if (CartTree[rchild].k2 <= k2)
		{
			flag = false;
			return;
		}
	}

	IsCartTree(lchild,min_k1,k1-1);
	IsCartTree(rchild,k1+1,max_k1);

}
int main()
{
	int n;
	int root;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> CartTree[i].k1 >> CartTree[i].k2 >> CartTree[i].lchild >> CartTree[i].rchild;
	}
	int label[1005];
	memset(label, 0, n * sizeof(int));//初始化
    //寻找根结点
	for (int i = 0; i < n; i++)
	{
		if (CartTree[i].lchild != -1)
		{
			label[CartTree[i].lchild] = 1;
		}
		if (CartTree[i].rchild != -1)
		{
			label[CartTree[i].rchild] = 1;
		}
	}
	for (int i = 0; i < n; i++)
	{
		if (!label[i])
		{
			root = i;
			break;
		}
	}
    //判断是否为笛卡尔树
	IsCartTree(root,INT_MIN,INT_MAX);
	if (flag)
	{
		cout << "YES\n";
	}
	else
	{
		cout << "NO\n";
	}
	return 0;
}


 
发布了80 篇原创文章 · 获赞 101 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/BigDream123/article/details/104181022