爆刷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;
}

 

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