zoukankan      html  css  js  c++  java
  • PAT-1135 Is It A Red-Black Tree(二叉查找树的创建和遍历)

    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.
    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)根节点是黑色 (2)红色节点的子节点均为黑色节点(包括NULL) (3) 所有从根节点到叶子节点的路径上经过的黑色节点数目相同。


    主要思路:题目考查的其实与红黑树关系不大,主要是二叉查找树的建立和遍历。首先根据给出的一系列节点创建二叉树,这里用到的是最基本的性质,左子树节点的值小于根节点的值且小于右子树节点的值,利用递归的方法将给出的节点插入树中。创建好之后,再利用递归的先序遍历对以上要求一一判断即可完成。

    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    
    typedef struct node {
        int val;
        struct node * left;
        struct node * right;
    } Node;
    Node * root;								//根节点
    int num_black;								//黑色节点数量
    bool is_red_black;							//是否是红黑树
    
    //动态分配新的节点
    Node * new_node(int val) {
        Node * p = (Node *) malloc(sizeof(Node));
        p->val = val;
        p->left = NULL;
        p->right = NULL;
        return p;
    }
    
    //添加节点
    Node * add_node(Node * node, int val) {
        if (node == NULL)   return new_node(val);
        if (abs(val) < abs(node->val))
            node->left = add_node(node->left, val);
        else
            node->right = add_node(node->right, val);
        return node;
    }
    void add(int val) {
        root = add_node(root, val);
    }
    
    //先序遍历
    void travel(Node * node, int num) {
        if (!is_red_black)      return;			//如果已经发现不是红黑树,停止后面的递归
        if (node == NULL) {						//遍历到NULL以后,判断路径中的黑色节点数是否与之前一致
            if (num_black == 0) 
                num_black = num;
            else if (num_black != num) 
                is_red_black = false;
            return;
        }
        if (node->val < 0) {					//红色节点:子节点必须为黑色节点(或NULL)
            if ((node->left != NULL && node->left->val < 0) || (node->right != NULL && node->right->val < 0))
                is_red_black = false;
        }
        else									//黑色节点:计数+1
            num++;								
        travel(node->left, num);
        travel(node->right, num);
    }
    
    int main(void) {
        int k, n, i, j;
        
        cin >> k;
        for (i = 0; i < k; i++) {
            root = NULL;
            num_black = 0;
            is_red_black = true;
            
            cin >> n;       
    		//创建二叉树
            for (j = 0; j < n; j++) {
                int v;
                cin >> v;
                add(v);
            }
            if (root->val < 0)					//红黑树根节点为黑色
                is_red_black = false;
            travel(root, 0);				
            if (is_red_black)					
                printf("Yes
    ");
            else
                printf("No
    ");
        }
    	
    	return 0;
    }


  • 相关阅读:
    多个数字和数字字符串混合运算规则
    关于js对象引用的小例子
    实现函数 isInteger(x) 来判断 x 是否是整数
    写一个少于 80 字符的函数,判断一个字符串是不是回文字符串
    关于数组排序
    事件委托(事件代理)的原理以及优缺点是什么?
    将url的查询参数解析成字典对象
    js dom操作获取节点的一些方法
    js中arguments的应用
    深度克隆---js对象引用
  • 原文地址:https://www.cnblogs.com/zhayujie/p/12941579.html
Copyright © 2011-2022 走看看