爆刷PAT(甲级)——之【1135】 Is It A Red-Black Tree (30 分)——简单模拟

题意:给一个红黑树的先序BST序列,判断是不是红黑树。

思路:本题没有红黑树的相当理解也OK,因为题目都给你描述清楚了。也没有任何AVL树旋转操作等。直接BST建树、遍历判断即可,应该算一个看名字很难其实考的是模拟的简单细节题。

坑点:1、这是多例输入,所以还要注意回收空间;其中一个小知识是,delete指针以后,系统只是回收了它的空间,但并不会改变指针的值。所以要根节点手动重新赋值为 NULL

2、红黑树中说叶子节点是黑色。这个“叶节点”指的是NULL节点。。。和平时写代码的时候的末尾节点概念不一样。。。所以本题中不用管它,不要没仔细看搞成  root->left==NULL&&root->right==NULL 的节点呀!

3、是个人问题。我的正负号用来判断结点颜色是在建树中的new环节,所以就灭去动它就建树了;而插入过程中选择是左子树还是右子树要去掉正负号来判断!结果未舍去正负号在左右子树选择的时候产生错误,还找了半天。。。所以编码思维和习惯要缜密一些,不然会有很多意想不到的问题。

 

Code:

代码里多了两个DEBUG用的函数,就懒得删了。

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
#define inf 100009
#define INF 0x3f3f3f3f
#define loop(x,y,z) for(x=y;x<z;x++)

int n,flag;
struct Node
{
    int v;
    Node *l,*r;
    bool color;//1红0黑
    Node(int v)
    {
        l=r=NULL;
        color=v<0;
        this->v=color?-v:v;
    }
}*root;

void deleteTree(Node *root)
{
    if(!root)return;
    deleteTree(root->l);
    deleteTree(root->r);
    delete root;
}
void print(Node *root)//DEBUG
{
    if(!root)return;
    printf("father: %d ,sons : %d %d \n",root->v,root->l?root->l->v:-1,root->r?root->r->v:-1);
    print(root->l);
    print(root->r);
}
Node* insert(Node *root,int v)
{
    if(!root)root=new Node(v);
    else
    {
        if(abs(v)<root->v)root->l=insert(root->l,v);
        else root->r=insert(root->r,v);
    }
    return root;
}
int checkColor(Node *root,Node *father)
{
    if(!root)return 0;//NULL节点结束,无黑色
    if(!flag)return -1;//结束剪枝,传递什么无所谓
    if(!father&&root->color)flag=0;//根节点黑色
    if(father&&father->color&&root->color)flag=0;//父红则子黑
    int l=checkColor(root->l,root);
    int r=checkColor(root->r,root);
    if(l!=r)flag=0;
    if(!root->color)l=l+1;//黑色统计
    return l;
}
int main()
{
    int i,j;
    int T;
    cin>>T;
    while(T--)
    {
        deleteTree(root);
        root=NULL;//重新声明
        cin>>n;
        loop(i,0,n)
        {
            cin>>j;
            root=insert(root,j);
            //print(root);printf("\n\n");
        }
        flag=1;
        checkColor(root,NULL);
        if(flag)printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章