PAT_A1135#Is It A Red-Black Tree

Source:

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

Description:

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.

rbf1.jpgrbf2.jpgrbf3.jpg
Figure 1 Figure 2 Figure 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

Keys:

Attention:

  • 应该注意到,红黑树( balanced binary search tree)并不是AVL树(self-balancing binary search tree),英文题描述题这里很容易产生误解;
  • 结点数目较少,给出先序遍历时,可以采用插入建树的方法;再次提醒,数据量较大时,会超时;
  • 根结点的父亲预设为负值,即为红色。这样从根结点遍历时,不必特判性质2,由性质4可以推出性质

Code:

 1 /*
 2 Data: 2019-06-26 15:30:16
 3 Problem: PAT_A1135#Is It A Red-Black Tree
 4 AC: 23:52
 5 
 6 题目大意:
 7 红黑树具有如下性质的平衡二叉树(非AVL树):
 8 1.结点非红即黑
 9 2.根结点为黑色
10 3.叶子结点(空结点)为黑色
11 4.红色结点的孩子均为黑色
12 5.任意结点到叶子结点构成的简单路径所含的黑色结点数目相同
13 现给定一棵二叉树,判定其是否为红黑树
14 输入:
15 第一行给出,测试数K<=20
16 第二行给出,结点总数N<=30
17 第三行给出,先序遍历,键值均正,负数表示红色结点
18 
19 基本思路:
20 建树,遍历一次二叉树
21 根据当前结点与父结点的关系,判断性质2,4
22 统计各结点左子树与右子树的黑色结点个数(类似于计算AVL树的平衡因子)
23 若相等,则符合性质5,并根据当前结点颜色,返回黑色结点个数
24 */
25 #include<cstdio>
26 #include<cmath>
27 using namespace std;
28 struct node
29 {
30     int data;
31     node *lchild,*rchild;
32 };
33 
34 void Insert(node *&root, int x)
35 {
36     if(root == NULL)
37     {
38         root = new node;
39         root->data = x;
40         root->lchild = root->rchild = NULL;
41     }
42     else if(abs(x) < abs(root->data))
43         Insert(root->lchild, x);
44     else
45         Insert(root->rchild, x);
46 }
47 
48 int Travel(node *root, int father, int &ans)
49 {
50     if(ans==0 || root==NULL)
51         return 0;
52     int l = Travel(root->lchild, root->data, ans);
53     int r = Travel(root->rchild, root->data, ans);
54     if(l!=r || (father<0 && root->data<0)){
55         ans=0;
56         return 0;
57     }
58     if(root->data<0)
59         return l;
60     else
61         return l+1;
62 }
63 
64 int main()
65 {
66 #ifdef ONLINE_JUDGE
67 #else
68     freopen("Test.txt", "r", stdin);
69 #endif // ONLINE_JUDGE
70 
71     int n,m,x;
72     scanf("%d", &m);
73     while(m--)
74     {
75         node *root = NULL;
76         scanf("%d", &n);
77         for(int i=0; i<n; i++)
78         {
79             scanf("%d", &x);
80             Insert(root, x);
81         }
82         int ans=1;
83         Travel(root,-1,ans);
84         if(ans)
85             printf("Yes\n");
86         else
87             printf("No\n");
88     }
89 
90     return 0;
91 }

 

posted @ 2019-05-28 21:25  林東雨  阅读(250)  评论(0编辑  收藏  举报