数据结构与算法题目集(中文)7-31 笛卡尔树 (25分) (二叉搜索+最小堆 注意建树方式、二叉搜索树的中序遍历是由小到大的)
1.题目
笛卡尔树是一种特殊的二叉树,其结点包含两个关键字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
2.题目分析
1.注意题目中的建树方式,是给了节点的左右节点编号,就需要设置一个数组,在输入的时候向节点各个位置赋值,最后未赋值的就是根节点(通过建立一个数组来寻找根节点 同 7-3 树的同构 (25分)https://pintia.cn/problem-sets/15/problems/711)
2.二叉搜索树的中序遍历是由小到大的,使用两个数组分别获取其中序遍历的结果,之后将其中一个进行排序,如果排序之后还与第二个数组相同就说明是二叉搜索树
3.最小堆的判别是通过递归,分别看左右子树的数字是否大于根节点
3.代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
int num;
int k1;
int k2;
int left;
int right;
}people[1001];
int ishead[1001];
int order1[1001];
int order2[1001];
bool idsearch = true;
int len = 0;
void find(int head)
{
if (head != -1)
{
find(people[head].left);
order1[len] = people[head].k1;
order2[len++] = people[head].k1;
find(people[head].right);
}
}
bool isheap = true;
void find2(int head)
{
if (people[head].left != -1)
{
int left = people[head].left;
if (people[left].k2 < people[head].k2)
{
isheap = false;
return;
}
find2(left);
}
if (people[head].right != -1)
{
int right = people[head].right;
if (people[right].k2 < people[head].k2)
{
isheap = false;
return;
}
find2(right);
}
}
int main()
{
for (int i = 0; i < 1001; i++)
{
ishead[i] = 0;
}
int n;
int head = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
people[i].num = i;
scanf("%d %d %d %d", &people[i].k1, &people[i].k2, &people[i].left, &people[i].right);
if(people[i].left!=-1)
ishead[people[i].left]=1;
if (people[i].right != -1)
ishead[people[i].right]=1;
}
for (int i = 0; i < n; i++)
{
if (ishead[i] == 0)
head = i;
}
find(head);
sort(order1, order1 + n);
for (int i = 0; i < n; i++)
{
if (order1[i] != order2[i])
idsearch = false;
}
if (idsearch == false)
{
printf("NO\n");
}
else
{
find2(head);
if(isheap==false)
printf("NO\n");
else
printf("YES\n");
}
}