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
    ");
    	}
    }
  • 相关阅读:
    DataAnnotations
    使用BizTalk实现RosettaNet B2B So Easy
    biztalk rosettanet 自定义 pip code
    Debatching(Splitting) XML Message in Orchestration using DefaultPipeline
    Modifying namespace in XML document programmatically
    IIS各个版本中你需要知道的那些事儿
    关于IHttpModule的相关知识总结
    开发设计的一些思想总结
    《ASP.NET SignalR系列》第五课 在MVC中使用SignalR
    《ASP.NET SignalR系列》第四课 SignalR自托管(不用IIS)
  • 原文地址:https://www.cnblogs.com/Jason66661010/p/12788871.html
Copyright © 2011-2022 走看看