PAT 1135 Is It A Red-Black Tree

原题链接:1135 Is It A Red-Black Tree (30分)
关键字:红黑树、BST树建树
参考的浒鱼鱼的博客:17年春季第四题 PAT甲级 1135 Is It A Red-Black Tree (30)

There is a kind of balanced binary search tree named red-black tree in the data structure. It has the following 5 properties:

  • Every node is either red or black.
  • The root is black.
  • Every leaf (NULL) is black.
  • If a node is red, then both its children are black.
  • 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.
PAT 1135 Is It A Red-Black Tree_第1张图片 PAT 1135 Is It A Red-Black Tree_第2张图片 PAT 1135 Is It A Red-Black Tree_第3张图片
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

题目大意: 给出一棵二叉搜索树的前序遍历,请你判断它是否是红黑树。
分析:
要判断是否满足红黑树五个定义:

  1. Every node is either red or black. (不用判断)
  2. The root is black.(根结点的值大于0)
  3. Every leaf (NULL) is black.(不用判断,但是可以用在4的判断里)
  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.(需要判断)

注意: 红黑树是一种二叉搜索树(BST)所以中序唯一确定,那给定前序就能确定一棵树了。

红黑树属于平衡二叉树。说它不严格是因为它不是严格控制左、右子树高度或节点数之差小于等于1。也就是说**红黑树并非严格控制左右孩子高度相差在1以内。**但红黑树高度依然是平均log(n),且最坏情况高度不会超过2log(n),这有数学证明。所以它算平衡树,只是不严格。不过严格与否并不影响数据结构的复杂度。

步骤:

  1. 根据先序建立一棵树,用链表表示(常规的BST的建树方法
  2. 判断根结点(题目所给先序的第一个点即根结点)是否是黑色
  3. 根据建立的树,从根结点开始遍历,如果当前结点是红色,判断它的孩子节点是否为黑色,递归返回结果
  4. 从根节点开始,递归遍历,检查每个结点的左子树的高度和右子树的高度(这里的高度指黑色结点的个数),比较左右孩子高度是否相等,递归返回结果

代码:

#include 
#include 
#include 
using namespace std;

const int maxn = 40;
int k, n;   //k询问数 n结点数
vector<int> arr;

struct node{
    int value;
    struct node *l, *r;
};

//建树
struct node* build(node *root, int v){
    if(root == NULL) {
        root = new node();
        root->value = v;
        root->l = root->r = NULL;
    }
    else if(abs(v) <= abs(root->value)) root->l = build(root->l, v);
    else root->r = build(root->r, v);
    return root;
}

//从根结点开始遍历,如果当前结点是红色,判断它的孩子节点是否为黑色,递归返回结果
bool judge1(node *root) {
    if (root == NULL) return true;
    if (root->value < 0) {
        if (root->l != NULL && root->l->value < 0) return false;
        if (root->r != NULL && root->r->value < 0) return false;
    }
    return judge1(root->l) && judge1(root->r);
}
//求出节点的高度(这里的高度指黑色结点的个数)
int getNum(node *root) {
    if (root == NULL) return 0;
    int l = getNum(root->l);
    int r = getNum(root->r);
    return root->value > 0 ? max(l, r) + 1 : max(l, r);
}
//检查每个结点的左子树的高度和右子树的高度(这里的高度指黑色结点的个数),比较左右孩子高度是否相等,递归返回结果
bool judge2(node *root) {
    if (root == NULL) return true;
    int l = getNum(root->l);
    int r = getNum(root->r);
    if(l != r) return false;
    return judge2(root->l) && judge2(root->r);
}

int main(){
    cin >> k;
    for(int i = 0; i < k; i ++ ){
        cin >> n;
        arr.resize(n);
        node *root = NULL;
        for(int i = 0; i < n; i ++ ){
            cin >> arr[i];
            root = build(root, arr[i]);
        }
        if(arr[0] < 0 || judge1(root) == false || judge2(root) == false) puts("No");
        else puts("Yes");

    }
    
    return 0;
}

你可能感兴趣的:(#,PAT甲级,红黑树,BST建树)