题目链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805346063728640
题解
题目要求
-
红黑树
在二叉搜索树的基础上,红黑树还具有以下特征
-
每个结点是红色或者黑色
-
根结点是黑色的
-
叶子结点(NULL)都是黑色
-
每个红色结点的两个子结点都是黑色
从每个叶子到根的所有路径上不能有两个连续的红色结点
-
每个结点到其每个叶子结点的所有路径都包含相同数目的黑色节点。
-
给定一颗二叉搜索树,请判断它是否是一个合法的红黑树。
-
输入
- K:正整数,不超过30,测试用例的数量
- N:正整数,不超过30,二叉树中结点的数量
- 二叉树的先序遍历结果:结点的值都是正整数,用负数代表红色结点
-
输出
判断每颗二叉搜索树是否是红黑树,是则输出
Yes
,否则输出No
。
解题思路
- 根据先序遍历结果和二叉搜索树的性质(左子树小于根结点小于右子树),递归构建二叉树
- 判断性质3:根结点是否是黑色
- 判断性质4,见代码中的函数judge1
- 判断性质5,见代码中的函数judge2
代码
// Problem: PAT Advanced 1135
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805346063728640
// Tags: Tree BST RBTree
#include <iostream>
#include <cmath>
using namespace std;
struct Node{
int val;
Node* left = nullptr;
Node* right = nullptr;
};
Node* build(Node* root, int v){
if (root == nullptr){
root = new Node();
root->val = v;
}
else if (abs(v) <= abs(root->val))
root->left = build(root->left, v);
else
root->right = build(root->right, v);
return root;
}
bool judge1(Node* root){
if (root == nullptr)
return true;
if (root->val < 0){
if (root->left != nullptr && root->left->val < 0)
return false;
if (root->right != nullptr && root->right->val < 0)
return false;
}
return judge1(root->left) && judge1(root->right);
}
int getDepth(Node* root){
if (root == nullptr)
return 0;
int ret = max(getDepth(root->left), getDepth(root->right));
return root->val > 0 ? ret + 1 : ret;
}
bool judge2(Node *root){
if (root == nullptr) return true;
if (getDepth(root->left) != getDepth(root->right))
return false;
return judge2(root->left) && judge2(root->right);
}
int main()
{
int k, n, val;
scanf("%d", &k);
while (k--){
scanf("%d", &n);
Node* root = nullptr;
for (int i = 0; i < n; i++){
scanf("%d", &val);
root = build(root, val);
}
if (root->val < 0 || !judge1(root) || !judge2(root))
printf("No
");
else
printf("Yes
");
}
return 0;
}
参考链接
https://blog.csdn.net/liuchuo/article/details/78037334
作者:@臭咸鱼
转载请注明出处:https://www.cnblogs.com/chouxianyu/
欢迎讨论和交流!