PAT-A1135 Is It A Red-Black Tree(30)

时间限制: 400 ms    内存限制: 64 MB    代码长度限制: 16 KB

 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.

For example, the tree in Figure 1 is a red-black tree, while the ones in Figure 2 and 3 are not.

figure1.jpgfigure2.jpgfigure3.jpg
Figure 1Figure 2Figure 3

For each given binary search tree, you are supposed to tell if it is a legal red-black tree.

Input Specification:

Each input file contains several test cases. The first line gives a positive integer K (≤30) which is the total number of cases. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the preorder traversal sequence of the tree. While all the keys in a tree are positive integers, we use negative signs to represent red nodes. All the numbers in a line are separated by a space. The sample input cases correspond to the trees shown in Figure 1, 2 and 3.

Output Specification:

For each test case, print in a line "Yes" if the given tree is a red-black tree, or "No" if not.

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

因为自己非科班,完全没学过红黑树,刚看标题的时候以为大佬们都很熟悉红黑树了,就先过了一遍算法导论13章红黑树,看完觉得也就那么回事,除了删除操作太长懒得看以外,5条性质还是很好掌握的。回头来看题,5条性质都给了,也没有插入删除操作,就是纯考性质,难度比A1123差远了,不要被那30分给懵逼了。

性质(《算法导论》):

1、每个结点或是 红色的,或是黑色的;

2、根结点是黑色的;

3、每个叶结点(NIL)是黑色的;

4、如果一个结点是红色的,则它的两个子结点都是黑色的;

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

题意:因为最多30组,每组30个,又给了先序,那就别客气,直接静态链表存储、递归建树。然后考察性质:因为最多30个结点,递归考虑每个结点,性质①不需考虑;性质②可以直接判断RBT[ROOT].color;性质③也没考到,不过说的比较含糊,这里的叶结点是指在真正的叶结点下面假想的两个NIL结点,主要为插入删除操作服务的,而真正的叶结点是红是黑都可以,这就解释了图①,不明白可以看一下《算法导论》;性质④判断当前为红色时,两个孩子是否为黑;性质⑤可以用归纳法证明红黑树的两个子树也是红黑树,只需递归的判断两子树黑高(简单路径上黑色结点的个数,不算自己)是否相等;

#define Abs(a) (((a)<0)?(0-(a)):(a))
#define RED 0
#define BLACK 1
#define NOTRBTREE -2
#define NULLPTR -1
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN=35;

int K,N,cnt,ROOT;
struct node{
    int key,color,left,right;
}RBT[MAXN];
int NewNode(int key){
    RBT[cnt].color=key<0?RED:BLACK;
    RBT[cnt].key=Abs(key);
    RBT[cnt].left=RBT[cnt].right=NULLPTR;
    return cnt++;
}
void Insert(int key,int &root){
    if(root==NULLPTR)
        root=NewNode(key);
    else if( Abs(key) < RBT[root].key )
        Insert(key,RBT[root].left);
    else
        Insert(key,RBT[root].right);
}
int isRBT(int root){
    if(RBT[ROOT].color==RED) return NOTRBTREE;  //根结点,性质2;
    if(root==NULLPTR) return 0;                                                                                                                        //https://blog.csdn.net/iserfj/article/details/82121467
    if(RBT[root].color==RED){               //红色结点的孩子必为黑色,性质4;
        if(RBT[root].left !=NULLPTR && RBT[RBT[root].left ].color==RED) return NOTRBTREE;
        if(RBT[root].right!=NULLPTR && RBT[RBT[root].right].color==RED) return NOTRBTREE;
    }
    int LCB=isRBT(RBT[root].left),RCB=isRBT(RBT[root].right);       /*  某结点到其任意叶结点的简单路径上黑色结点的   */
    if(LCB==NOTRBTREE || RCB==NOTRBTREE) return NOTRBTREE;          /*  个数相等,可递归的判断其左右孩子到其叶结点   */
    return LCB==RCB?LCB+(RBT[root].color==BLACK?1:0):NOTRBTREE;     /*  的简单路径上黑色结点的个数是否相等,性质5;    */
}
int main()
{
    int key;
    scanf("%d",&K);
    for(int i=0;i<K;++i){
        cnt=0;
        ROOT=NULLPTR;
        scanf("%d",&N);
        for(int j=0;j<N;++j){
            scanf("%d",&key);
            Insert(key,ROOT);
        }
        printf("%s\n",isRBT(ROOT)!=NOTRBTREE?"Yes":"No");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值