这题真是修bug修到崩溃!
题目
废话
这题最大问题在于图和描述不符
而且描述为英文,加重了题意的模糊
看了网上的一些解法,大都会觉得这题出的很奇怪
表述非常不明确
理解题意
1.题目中的图是这样
而真正意义上的红黑树是这样的
发现区别了嘛?
原因就在于要挂这些黑色的叶节点
2.可能你还是觉得奇怪?
参考这位同学的测试点推测
其中提到
1
3
1 2 -3
No
你可以想想为什么这种树是no
3.题目中有2句话,也暗示了图的不对劲
具体写法
-
常规按照前序和BST生成树
-
再按照上述理解,插入空的黑色叶节点
必须用后序遍历插入 -
然后判断
对于红结点孩子全黑,我这里用了额外的容器保存结点,这样便于直接扫描全部红结点
对于判断黑结点数量,必须用先序遍历
4.另外我这里对树进行删除,从而节约空间
代码
#include<bits/stdc++.h>
using namespace std;
#define black 0
#define red 1
typedef struct node {
int color;
int key;
struct node* lchild, * rchild;
node(int x,int y) {
key = abs(x);
color = y;
lchild = rchild = NULL;
}
}RBTree;
int situation{ 0 };
int quantity{ 0 };
vector<RBTree*>static_node;
vector <int>hight;
RBTree* insert(int x, RBTree* root);
RBTree* insertNULL(RBTree* T);
void ClearTree(RBTree* root);
bool PrintJudge(RBTree* root);
void walk(int high, RBTree* T);
int main() {
scanf("%d", &situation);
RBTree* root = NULL;
for (int i = 0; i < situation; i++) {
scanf("%d", &quantity);
int x;
for (int j = 0; j < quantity; j++) {
scanf("%d", &x);
root = insert(x, root);
}
root = insertNULL(root);
PrintJudge(root) ? printf("Yes\n") : printf("No\n");
ClearTree(root);
root = NULL;//因为删掉内存,root会被扔到奇怪的地方,因此需重新赋值NULL
hight.clear();
static_node.clear();
}
return 0;
}
RBTree* insert(int x, RBTree* root) {
if (root == NULL) {
int y;
x > 0 ? y = black : y = red;
root = new RBTree(x, y);
static_node.push_back(root);
}
else {
abs(x) > root->key ? root->rchild = insert(x, root->rchild) : root->lchild = insert(x, root->lchild);
}
return root;
}
RBTree* insertNULL(RBTree* T) {//注意不能在插入时进行同步插入NULL结点,原因是后序可能有点正好放入这个空结点
if (T->lchild != NULL)
insertNULL(T->lchild);
if (T->rchild != NULL)
insertNULL(T->rchild);
if (T->lchild == NULL) {
RBTree* q = new node(0, black);
T->lchild = q;
}
if (T->rchild == NULL) {
RBTree* p = new node(0, black);
T->rchild = p;
}
return T;
}
void ClearTree(RBTree* root) {
if (root != NULL) {
ClearTree(root->lchild);
ClearTree(root->rchild);
delete(root);
}
}
bool PrintJudge(RBTree* root) {
if (root->color == red)
return false;
for (auto i : static_node) {
if (i->color == red && i->lchild != NULL && i->rchild != NULL) {
if (i->lchild->color != black || i->rchild->color != black)
return false;
}
}
int count{ 0 };
walk(count, root);
for (auto i = hight.begin(); i != hight.end(); i++) {
if (hight[0] != *i)
return false;
}
return true;
}
void walk(int high, RBTree* T) {//遍历高度
if (T->color == black)
(high)++;
if (T->lchild == NULL && T->rchild == NULL) {
hight.push_back(high);
return;
}
if (T->lchild != NULL)
walk(high, T->lchild);
if (T->rchild != NULL)
walk(high, T->rchild);
}