1135 Is It A Red-Black Tree
分数 30
全屏浏览题目
切换布局
作者 CHEN, Yue
单位 浙江大学
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.
Figure 1 | Figure 2 | Figure 3 |
For each given binary search tree, you are supposed to tell if it is a legal red-black tree.
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.
Output Specification:
For each test case, print in a line "Yes" if the given tree is a red-black tree, or "No" if not.
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
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
#include<bits/stdc++.h>
using namespace std;
const int N=40;
int n;
int pre[N],in[N];
map<int,int>pos;
bool ans;//作为判断是否为红黑树的标志
int build(int il,int ir,int pl,int pr,int &sum){
int root=pre[pl];//根结点
int k=pos[abs(root)];//根结点在中序序列的位置
if(il>k||ir<k){//若是不合法的序列直接返回
ans=false;
return 0;
}
int left=0,right=0,ls=0,rs=0;//左右孩子和左右子树的黑节点个数
if(il<k)left=build(il,k-1,pl+1,pl+1+k-1-il,ls);//若有左子树,则递归
if(ir>k)right=build(k+1,ir,pl+k-il+1,pr,rs);//若有右子树,则递归
if(ls!=rs)ans=false;//左右子树黑节点个数不同则置为false
sum=ls;
if(root<0){//若当前结点是红色
if(left<0||right<0)ans=false;//此时若左孩子或右孩子是红色则置为false
}
else sum++;//否则黑节点个数加一
return root;//返回根结点
}
int main(){
int k;
cin>>k;
while(k--){//k组
cin>>n;
for(int i=0;i<n;i++){//输入先序序列
cin>>pre[i];
in[i]=abs(pre[i]);
}
sort(in,in+n);//得到中序序列
pos.clear();//每次用前需清空
for(int i=0;i<n;i++)pos[in[i]]=i;//记录在中序下的位置
ans=true;
int sum;//记录各结点到叶结点的黑结点数
int root=build(0,n-1,0,n-1,sum);//根结点
if(root<0)ans=false;//若根结点是红色,则置为false
if(ans)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}