1135 Is It A Red-Black Tree (30分)

本文介绍了红黑树这一平衡二叉搜索树的特性,并通过先序遍历的结果来建立红黑树。文章重点讨论了如何根据红黑树的性质4(红色节点的子节点必须为黑色)和性质5(每个节点到其所有叶子节点的简单路径上相同数量的黑色节点)进行递归判断。内容包括如何根据先序遍历构建树结构,以及实现检查性质4和5的递归函数。
摘要由CSDN通过智能技术生成

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.

正数是黑,负数是红。题目给出先序遍历的结果。本题考察对树递归操作的基本功~

然后我们来看要求:

1  无需判断

2  根为正数

3  无需判断

4   红色结点的孩子都为黑色结点

5   对每个结点,所有从该节点到后代叶子结点的简单路径包含相同个数的黑色结点。

4和5需要单独写函数

按如下几步:

1  给出了先序遍历结果,红黑树又是二叉搜索树,据此建树(红黑树不是AVL树)

2  判断4,写递归

从根结点开始遍历,如果当前结点是红⾊,判断它的孩⼦节点是否为⿊⾊,递归返回结果

bool judge2(node* root){
    if(root==NULL) return true;
    if(root->data<0){
        if(root->left!=NULL&&root->left->data<0) return false;
        if(root->right!=NULL&&root->right->data<0) return false;
    }
    return judge2(root->left)&&judge2(root->right);
}

3 判断5,写一个getnum的函数,然后递归判断

int getNum(node* root){
    if(root==NULL) return 0;
    int l=getNum(root->left);
    int r=getNum(root->right);
    return root->data>0? max(l,r)+1:max(l,r);
}
bool judge5(node* root){
    if(root==NULL) return true;
    int l=getNum(root->left);
    int r=getNum(root->right);
    if(l!=r) return false;
    return judge5(root->left)&&judge5(root->right);
}
#include<bits/stdc++.h>
using namespace std;
// (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.这怎么解决?
struct node{
    node* left;
    node* right;
    int data;
};
node* newNode(int data){
    node* root=new node();
    root->data=data;
    root->left=root->right=NULL;
    return root;
}
void insert(node* &root,int x){
    if(root==NULL){
        root=newNode(x);
    }else if(abs(x)<=abs(root->data)) insert(root->left,x);
    else insert(root->right,x);
}
bool judge2(node* root){
    if(root==NULL) return true;
    if(root->data<0){
        if(root->left!=NULL&&root->left->data<0) return false;
        if(root->right!=NULL&&root->right->data<0) return false;
    }
    return judge2(root->left)&&judge2(root->right);
}
int getNum(node* root){
    if(root==NULL) return 0;
    int l=getNum(root->left);
    int r=getNum(root->right);
    return root->data>0? max(l,r)+1:max(l,r);
}
bool judge5(node* root){
    if(root==NULL) return true;
    int l=getNum(root->left);
    int r=getNum(root->right);
    if(l!=r) return false;
    return judge5(root->left)&&judge5(root->right);
}
const int maxn=31;
int d[maxn];
int main(){
    int n;
    cin>>n;
    while(n--){
        int k;
        cin>>k;
        fill(d,d+maxn,0);
        node* root=NULL;
        for(int i=0;i<k;i++){
            cin>>d[i];
            insert(root,d[i]);
        }
        if(d[0]<0||!judge2(root)||!judge5(root)){
            cout<<"No"<<endl;
        }else{
            cout<<"Yes"<<endl;
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值