• PAT甲级1135Is It A Red-Black Tree


    题目链接

    https://pintia.cn/problem-sets/994805342720868352/problems/994805346063728640

    题解

    题目要求

    • 红黑树

      在二叉搜索树的基础上,红黑树还具有以下特征

      1. 每个结点是红色或者黑色

      2. 根结点是黑色的

      3. 叶子结点(NULL)都是黑色

      4. 每个红色结点的两个子结点都是黑色

        从每个叶子到根的所有路径上不能有两个连续的红色结点

      5. 每个结点到其每个叶子结点的所有路径都包含相同数目的黑色节点。

    给定一颗二叉搜索树,请判断它是否是一个合法的红黑树。

    • 输入

      • K:正整数,不超过30,测试用例的数量
      • N:正整数,不超过30,二叉树中结点的数量
      • 二叉树的先序遍历结果:结点的值都是正整数,用负数代表红色结点
    • 输出

      判断每颗二叉搜索树是否是红黑树,是则输出Yes,否则输出No

    解题思路

    1. 根据先序遍历结果和二叉搜索树的性质(左子树小于根结点小于右子树),递归构建二叉树
    2. 判断性质3:根结点是否是黑色
    3. 判断性质4,见代码中的函数judge1
    4. 判断性质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/

    欢迎讨论和交流!


  • 相关阅读:
    配置多个Git账号(windows 10)
    Windows下的WSL和Docker导入导出迁移
    MySQL数据统计
    angular动画(一)
    ngzorro UI源码技巧(二)
    ngzorro UI源码技巧(一)
    angular技巧
    让angular表单更简单
    angular 粘合性指令
    姿态解析
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/13674136.html
Copyright © 2020-2023  润新知