数据结构与算法题目集(中文)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");

	}
	
}

 

posted @ 2020-02-09 19:15  Jason66661010  阅读(244)  评论(0编辑  收藏  举报