原文链接:我的个人博客
原题链接
PAT 1135 Is It A Red-Black Tree
考点
树
思路
红黑树需要满足的条件。
- 树的根节点是黑色
- 红色节点的两个左右节点均是黑色
- 每个路径的黑色节点个数相同
因为红黑树本身的特性,是特殊的二叉查找树,因此,前序序列即是插入的序列。
代码
#include <bits/stdc++.h>
using namespace std;
vector<int> arr;
struct node{
int val;
struct node *left,*right;
};
node* build(node *root,int v){
if(root == NULL){
root = new node();
root->val = v;
root->left=root->right = NULL;
}else if(abs(v)<=abs(root->val)){
root->left = build(root->left,v);
}else{
root->right = build(root->right,v);
}
return root;
}
//判断红节点的子节点是否为黑节点
bool fun1(node *root){
if(root == NULL) return true;
if(root->val<0){
if(root->left!=NULL && root->left->val<0) return false;
if(root->right!=NULL &&root->right->val<0) return false;
}
return fun1(root->left)&&fun1(root->right);
}
int getNum(node *root){
if(root == NULL) return 0;
int l = getNum(root->left);
int r = getNum(root->left);
return root->val>0? max(l,r)+1:max(l,r);
}
//判断每个路径的黑色节点是否相同
bool fun2(node *root){
if(root ==NULL) return true;
int l = getNum(root->left);
int r = getNum(root->right);
if(l!=r) return false;
return fun2(root->left)&&fun2(root->right);
}
int main(){
int k,n;
scanf("%d",&k);
for(int i=0;i<k;i++){
scanf("%d",&n);
arr.resize(n);
node *root = NULL;
for(int j=0;j<n;j++){
scanf("%d",&arr[j]);
root = build(root,arr[j]);
}
if(arr[0]<0||fun1(root)==false||fun2(root)==false)
printf("No\n");
else
printf("Yes\n");
}
}