【PAT】1135.Is It A Red-Black Tree (30)【递归】

题目描述

There is a kind of balanced binary search tree named red-black tree in the data structure. It has the following 5 properties:

(1) Every node is either red or black.
(2) The root is black.
(3) Every leaf (NULL) is black.
(4) If a node is red, then both its children are black.
(5) For each node, all simple paths from the node to descendant leaves contain the same number of black nodes.

For example, the tree in Figure 1 is a red-black tree, while the ones in Figure 2 and 3 are not.

rbf1.jpg rbf2.jpg rbf3.jpg

For each given binary search tree, you are supposed to tell if it is a legal red-black tree.

翻译:在数据结构中有一种平衡二叉树叫做红黑树。它有以下5个特征:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NULL)是黑色。
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
例如,图一是一棵红黑树,图二图三均不是。

Input Specification:

Each input file contains several test cases. The first line gives a positive integer K (≤30) which is the total number of cases. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the preorder traversal sequence of the tree. While all the keys in a tree are positive integers, we use negative signs to represent red nodes. All the numbers in a line are separated by a space. The sample input cases correspond to the trees shown in Figure 1, 2 and 3.

翻译:每个输入文件包含多组测试数据。第一行给出一个正整数K (≤30) ,表示测试总数。对于每组测试数据,第一行给出一个正整数N (≤30),表示二叉树的节点总数。第二行给出树的先序遍历数列。树上所有的关键值都是正整数,我们使用负数标记来表示红色节点。一行内所有数字之间用空格隔开。样例对应的树分别为图1,图2,图3。

Output Specification:

For each test case, print in a line “Yes” if the given tree is a red-black tree, or “No” if not.

翻译:对于每组测试数据,输出一行 "Yes"如果给定的树是红黑树,否则输出 “No”。


Sample Input:

3
9
7 -2 1 5 -4 -11 8 14 -15
9
11 -2 1 -7 5 -4 8 14 -15
8
10 -7 5 -6 8 15 -11 17


Sample Output:

Yes
No
No


解题思路

先根据先序遍历和搜索二叉树定义来建树,然后再递归判断是否符合条件。注意每次计算完一个样例时对数组进行清零。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<algorithm>
#define INF 99999999
#define bug puts("Hello\n")
using namespace std;
int K,N;
int node[35][3];//0存储节点值,1存储左孩子,2存储右孩子 
int color[35];//1表示红,0表示黑 
void Insert(int root,int a){
	if(node[a][0]<=node[root][0]){
		if(node[root][1])Insert(node[root][1],a);
		else node[root][1]=a;
	}else{
		if(node[root][2])Insert(node[root][2],a);
		else node[root][2]=a;		
	}
} 
int Judge(int root){
	if(!node[root][1]&&!node[root][2]){
		if(!color[root])return 1;
		else return 0;
	}
	if(color[root]){
		if(color[node[root][1]]||color[node[root][2]])return -1;
	}
	int lc=0,rc=0;
	if(node[root][1]){
		lc=Judge(node[root][1]);
		if(lc<0)return -1;
	}
	if(node[root][2]){
		rc=Judge(node[root][2]);
		if(rc<0)return -1;		
	}
	if(lc==rc)return lc+!color[root];
	else return -1;
}
int main(){
	scanf("%d",&K);
	for(int k=0;k<K;k++){
		scanf("%d",&N);
		int flag=0;
		int data;
		memset(node,0,sizeof(node));
		memset(color,0,sizeof(color));
		for(int i=0;i<N;i++){
			scanf("%d",&data);
			if(data<0){
				if(i==0)flag=1;
				node[i][0]=-data,color[i]=1;
			}else{
				node[i][0]=data;
			}
			if(i)Insert(0,i);
		}
		if(flag||Judge(0)==-1)printf("No\n");
		else printf("Yes\n");
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值