1135 Is It A Red-Black Tree (30 分)
Is It A Red-Black Tree
题目描述:
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
思路:
只有三种情况不符合,根结点是负值,连续两个红色,每条path的黑色节点数量不同,其他都是yes
代码:
#include "iostream"
using namespace std;
int m;
int num[31];
bool is_valid;
struct Node {
Node *left, *right;
int num;
bool isRed;
};
Node *buildNode(int a, bool is_red) {
Node *node = (Node *) malloc(sizeof(Node));
node->num = a;
node->isRed = is_red;
node->right = nullptr;
node->left = nullptr;
return node;
};
Node *build(Node *root, int a, bool is_red) {
if (root == nullptr) {
return buildNode(a, is_red);
}
if (a > root->num) root->right = build(root->right, a, is_red);
else root->left = build(root->left, a, is_red);
return root;
}
int blackNodeNums = 0;
void dfs(Node *root, int blackNodeNum) {
//如果知道错的就直接return
if (is_valid) return;
if (root == nullptr) {
if (blackNodeNums == 0) blackNodeNums = blackNodeNum;
else if (blackNodeNums != blackNodeNum) is_valid = true;
return;
}
if (!root->isRed) {
dfs(root->left, blackNodeNum + 1);
dfs(root->right, blackNodeNum + 1);
} else {
dfs(root->left, blackNodeNum);
dfs(root->right, blackNodeNum);
}
}
void dfsRed(Node *root) {
if (root->left != nullptr) {
if (root->isRed && root->left->isRed) is_valid = true;
else dfsRed(root->left);
}
if (root->right != nullptr) {
if (root->isRed && root->right->isRed) is_valid = true;
else dfsRed(root->left);
}
}
int main() {
int n;
cin >> n;
while (n--) {
cin >> m;
for (int i = 0; i < m; i++) {
cin >> num[i];
}
is_valid = false;
blackNodeNums = 0;
if (num[0] < 0) {
cout << "No" << endl;
continue;
}
Node *root = nullptr;
for (int i = 0; i < m; i++) {
if (num[i] < 0) root = build(root, -num[i], true);
else root = build(root, num[i], false);
}
dfs(root, 0);
if (is_valid) {
cout << "No" << endl;
continue;
}
dfsRed(root);
if (is_valid) {
cout << "No" << endl;
continue;
}
cout << "Yes" << endl;
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!


