您好,欢迎来到品趣旅游知识分享网。
搜索
您的当前位置:首页PAT_甲级_1135 Is It A Red-Black Tree (30point(s)) (C++)【红黑树/先序+中序构建二叉树/判断红黑树性质】

PAT_甲级_1135 Is It A Red-Black Tree (30point(s)) (C++)【红黑树/先序+中序构建二叉树/判断红黑树性质】

来源:品趣旅游知识分享网


1,题目描述

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

题目大意

判断一棵树是否为红黑树。为了简便,题目中正数为黑色节点,负数代表红色节点,值的相对大小通过绝对值比较。

红黑树满足的性质:

  • (1) Every node is either red or black.:节点非黑即红;
  • (2) The root is black.:根节点为黑色(根节点大于0);
  • (3) Every leaf (NULL) is black.:规定空节点(NULL)为黑色;
  • (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.:对每个结点,从该节点向下延申到每个叶子节点的路径中,所有路径含有的黑色节点数目相同;

 知识补充

这篇文章讲解的很详细;

这篇文章介绍实例,动态构建红黑树,挺有意思

 

2,思路

(解决这道题不需要对红黑树有很深刻的认识,只需要判断是否符合性质即可)

用到先序加中序遍历构建二叉树,具体操作可以参考这里

数据结构

  • struct node{
        int key;
        node *left = NULL, *right = NULL;
    };动态二叉链表存储节点;
  • int pre[35], in[35]:先序遍历序列,中序遍历序列(即数组从小到大排序);
  • unordered_set<int> record:记录节点到所有叶节点路径中,黑色节点的数目,若record.size()==1则该节点符合条件5,否则说明黑色节点数目不唯一;

算法

 

3,AC代码

#include<bits/stdc++.h>
using namespace std;
struct node{
    int key;
    node *left = NULL, *right = NULL;
};
int pre[35], in[35], K, N, key;                 //K判断次数 N节点数
bool flag;
unordered_set<int> record;                      //记录节点到所有叶节点路径中 黑色节点的数目 若record.size()==1则该节点符合条件5

bool cmp1(int a, int b){ return abs(a) < abs(b);}
void buildTree(node *&r, int root, int left, int right){// !!!*&
    if(left > right) return;
    if(r == NULL){
        r = new node();
        r->key = pre[root];
    }
    int i = left;
    while(i <= right && in[i] != pre[root])
        i++;
    buildTree(r->left, root+1, left, i-1);
    buildTree(r->right, root+(i-left)+1, i+1, right);
}
void getBlackNum(node *n, int num){
    if(n == NULL || n->key > 0)                 //黑色节点
        num++;
    if(n == NULL){
        record.insert(num);
        return;
    }
    getBlackNum(n->left, num);
    getBlackNum(n->right, num);
}
void dfsJudge(node *tree){
    if(tree != NULL && flag == true){
        record.clear();
        getBlackNum(tree, 0);
        if(record.size() > 1) flag = false;     //判断该节点对应的条件5
        if(flag == true && tree->key < 0){      //判断红色节点是否满足条件4
            if(tree->left != NULL && tree->left->key < 0)
                flag = false;
            if(tree->right != NULL && tree->right->key < 0)
                flag = false;
        }
        if(flag == true)
            dfsJudge(tree->left);
        if(flag == true)
            dfsJudge(tree->right);
    }
    else return;
}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    cin>>K;
    for(int i = 0; i < K; i++){
        flag = true;
        scanf("%d", &N);
        for(int j = 0; j < N; j++){
            scanf("%d", &pre[j]);
            if(pre[j] == 0) flag = false;
        }
        if(pre[0] <= 0)
            flag = false;
        else{
            memcpy(in, pre, N*sizeof(int));     //pre数组拷贝到in数组中
            sort(in, in + N, cmp1);             // !!!不是sort(pre, pre + N, cmp1);
            node *root = NULL;
            buildTree(root, 0, 0, N-1);
            dfsJudge(root);
        }
        printf("%s\n", flag ? "Yes":"No");
    }
    return 0;
}

 

4,解题过程

一发入魂o(* ̄▽ ̄*)ブ

 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- pqdy.cn 版权所有 赣ICP备2024042791号-6

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务