您的位置:首页 > 其它

浙大PAT 4-09. 笛卡尔树 (解题思路)

2014-03-30 18:13 513 查看

4-09. 笛卡尔树

时间限制
400 ms

内存限制
32000 kB

代码长度限制
8000 B

判题程序
Standard

笛卡尔树是一种特殊的二叉树,其结点包含两个关键字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

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

NO

3
7
8 27 5 1
9 40 -1 -1
10 20 0 3
12 22 -1 4
15 21 6 -1
5 35 -1 -1
13 23 -1 -1

NO

4
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 21 -1 4
11 22 –1 -1
5 35 -1 -1

NO

5
9
11 5 3 -1
15 3 4 7
5 2 6 0
6 8 -1 -1
9 6 -1 8
10 1 2 1
2 4 -1 -1
20 7 -1 -1
12 9 -1 -1

NO

6
1
1 1 -1 -1

YES

//二叉排序树的中序遍历一定是一个从小到大排序的数组,这题我在判断是否是二叉树的时候分了2步, 先得到中序的数组然后来进行判断。方法有点笨。

//另外题目给的测试数据有问题,有几处-1的负号不是同一种类型的。大家注意下,自己改回来

#include <iostream>
#include <deque>
using namespace std;

typedef struct
{
int K1;
int K2;
int lChild;
int rChild;
}BNode;

deque<BNode> de;

deque<int> tde;

bool a[1005] = {false};

int sum = 0;

void PreTraval(BNode root)
{
if(root.lChild != -1)
PreTraval(de[root.lChild]);
tde.push_back(root.K1);
if(root.rChild != -1)
PreTraval(de[root.rChild]);
}

bool IsSDD(BNode root)
{
if(root.lChild == -1 && root.rChild == -1)
return true;
else if(root.lChild == -1 && root.rChild != -1)
{
if(de[root.rChild].K2 > root.K2)
return IsSDD(de[root.rChild]);
else
return false;
}
else if(root.lChild != -1 && root.rChild == -1)
{
if(de[root.lChild].K2 > root.K2)
return IsSDD(de[root.lChild]);
else
return false;
}
else
{
if(root.K2 < de[root.lChild].K2 && root.K2 < de[root.rChild].K2)
return IsSDD(de[root.lChild]) && IsSDD(de[root.rChild]);
else
return false;
}
}

bool IsBST()
{
for(int i = 1; i < tde.size(); ++i)
{
if(tde[i] <= tde[i-1])
return false;
}
return true;
}

int main()
{
int n;
cin>>n;
while(n--)
{
BNode tn;
scanf("%d%d%d%d", &tn.K1, &tn.K2, &tn.lChild, &tn.rChild);
//	cin>>tn.K1>>tn.K2>>tn.lChild>>tn.rChild;
if(tn.lChild >= 0)
a[tn.lChild] = true;
if(tn.rChild >= 0)
a[tn.rChild] = true;
de.push_back(tn);
}
int rootIndex = 0;
for(int i = 0; i < de.size(); ++i)
if(!a[i])
{
rootIndex = i;
break;
}
PreTraval(de[rootIndex]);

if(IsBST() && IsSDD(de[rootIndex]))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: