zoukankan      html  css  js  c++  java
  • PAT (Advanced Level) Practice 1135 Is It A Red-Black Tree (30分) (红黑树知识+建树+判断)

    1.题目

    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.jpg rbf2.jpg rbf3.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

    2.题目分析

    1.红黑树:

    • 性质1:每个节点要么是黑色,要么是红色。
    • 性质2:根节点是黑色。
    • 性质3:每个叶子节点(NIL)是黑色。
    • 性质4:每个红色结点的两个子结点一定都是黑色。
    • 性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。

    参考:https://www.jianshu.com/p/e136ec79235c
     

     2.建树

    红黑树的中序遍历是从小到大的(建树用了两种小小不同的形式)

    3.判断

    计算从底部到根的黑节点的个数(未将为空的叶子节点算入,但是不影响结果),同时看一个红节点的两个子节点,要不两个都为空,要不两个都是黑节点,否则为NO

    3.代码

    #include<iostream>
    #include<vector>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef struct node* tree;
    struct node
    {
    	int data;
    	tree left;
    	tree right;
    };
    tree creat(tree t,int root, int ins,int ine,vector<int>pre,vector<int>in,vector<int>mark)
    {
    	if (ins>ine)return NULL;
    	if (t == NULL)t = (tree)malloc(sizeof(struct node));
    	t->data = pre[root]*mark[root];
    	t->left = t->right = NULL;
    	int i = ins;
    	while (in[i] != pre[root])i++;
        if(i<=ine)
    	{t->left=creat(t->left, root + 1, ins,i-1, pre, in, mark);
    	t->right = creat(t->right, root + i + 1-ins,  i + 1,ine, pre,in,mark);
        }
    	return t;
    }
    
    // tree creat(tree t, int pres,int pree, int ins, int ine, vector<int>pre, vector<int>in, vector<int>mark)
    // {
    // 	if (pres>pree)return NULL;
    // 	if (t == NULL)t = (tree)malloc(sizeof(struct node));
    // 	t->data = pre[pres] * mark[pres];
    // 	t->left = t->right = NULL;
    // 	int i = ins;
    // 	while (i<ine&&in[i] != pre[pres])i++;
    // 	t->left = creat(t->left, pres + 1,pres+i-ins, ins, i - 1, pre, in, mark);
    // 	t->right = creat(t->right, pres + i + 1 - ins,pree, i + 1, ine, pre, in, mark);
    // 	return t;
    // }
    
    bool ok = true;
    int judge(tree t)
    {
    	int l, r;
    	if (t == NULL)return 0;
    
    		 l = judge(t->left);
    		 r = judge(t->right);
    
    	if (l != r) { ok = false; return l; }
    	if (t->data < 0)
    	{
    		if ((t->left == NULL&&t->right == NULL) || (t->left != NULL&&t->right != NULL&&t->left->data>0 && t->right->data > 0));
    		else ok = false;
    	}
    	if(t->data>0)
    	return l+1;
    	else return l;
    }
    int main()
    {
    	int k,n,temp;
    	scanf("%d", &k);
    	for (int i = 0; i < k; i++)
    	{
    		ok = true;
    		scanf("%d", &n);
    		vector<int>pre,in;
    		vector<int>mark(n, 1);
    		for (int j = 0; j < n; j++)
    		{
    			scanf("%d", &temp);
    			if (temp < 0)mark[j] = -1;
    			pre.push_back(abs(temp));
    			in.push_back(abs(temp));
    		}
    		sort(in.begin(), in.end());
    		tree t = NULL;
    		t = creat(t,0, 0,n-1, pre, in, mark);
    		//t = creat(t, 0,n-1, 0, n - 1, pre, in, mark);
    		if (t->data < 0) { printf("No
    "); continue; }
    		judge(t);
    		if (ok)printf("Yes
    ");
    		else printf("No
    ");
    	}
    }
  • 相关阅读:
    Python语言程序设计(1)--实例1和基本知识点
    前端学习笔记--函数
    知乎推荐书籍整理
    第六周周总结
    第五周总结
    第四周周总结
    第三周周总结
    第二周总结
    第一周总结
    项目目标
  • 原文地址:https://www.cnblogs.com/Jason66661010/p/12788871.html
Copyright © 2011-2022 走看看