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
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node{
struct node * lchild;
struct node * rchild;
int data;
};
node * build(node * root, int v) {
if(root == NULL) {
root = new node();
root -> data = v;
root -> lchild = root -> rchild = NULL;
} else if(abs(v) <= abs(root->data))
root -> lchild = build(root -> lchild, v);
else
root -> rchild = build(root -> rchild, v);
return root;
}
node * creat_tree(vector<int> &pre_order, vector<int> &in_order, int pre_start, int pre_end, int in_start, int in_end){
// 用前序、中序建树会出现段错误,可能会有节点有相同的值
if(pre_start > pre_end || in_start > in_end){
return NULL;
}
node * root = new node;
root -> data = pre_order[pre_start];
int i;
for(i = 0; i < in_order.size(); i++){
if(abs(pre_order[pre_start]) == in_order[i])
break;
}
root -> lchild = creat_tree(pre_order, in_order, pre_start + 1, pre_start + i - in_start, in_start, i - 1);
root -> rchild = creat_tree(pre_order, in_order, pre_end - in_end + i + 1, pre_end, i + 1, in_end);
return root;
}
bool is_child_pre(node * t){ //是否红节点的孩子节点是黑节点
if(t == NULL)
return true;
if(t -> data < 0){
if(t -> lchild != NULL && t -> lchild -> data < 0)
return false;
if(t -> rchild != NULL && t -> rchild -> data < 0)
return false;
}
return is_child_pre(t -> lchild) & is_child_pre(t -> rchild);
}
int black_level(node * t){
if(t == NULL)
return 0;
int l = black_level(t -> lchild);
int r = black_level(t -> rchild);
return t -> data > 0 ? max(l, r) + 1 : max(l, r);
}
bool is_black_level(node * t){ //是否任意点到叶子节点黑节点个数(高度)相同
if(t == NULL)
return true;
int l = black_level(t -> lchild);
int r = black_level(t -> rchild);
if(l != r)
return false;
return is_black_level(t -> lchild) & is_black_level(t -> rchild);
}
int main(){
int k;
cin >> k;
for(int i = 0; i < k; i++){
int n;
scanf("%d", &n);
vector<int> pre_order(n);
// vector<int> in_order(n);
node * tree = NULL;
for(int j = 0; j < n; j++){
scanf("%d", &pre_order[j]);
// in_order[j] = abs(pre_order[j]);
tree = build(tree, pre_order[j]);
}
// sort(in_order.begin(), in_order.end());
// tree = creat_tree(pre_order, in_order, 0, n - 1, 0, n - 1);
bool flag1 = true;
bool flag2 = true;
bool flag3 = true;
if(pre_order[0] < 0){
flag1 = false;
}
flag2 = is_child_pre(tree);
flag3 = is_black_level(tree);
if(flag1 && flag2 && flag3){
printf("Yes\n");
}else
{
printf("No\n");
}
}
return 0;
}