1135 Is It A Red-Black Tree
Posted kkmjy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1135 Is It A Red-Black Tree相关的知识,希望对你有一定的参考价值。
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:
-
(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
题意:
给出k个二叉搜索树的前序序列,判断该树是否为红黑树。
思路:
红黑树的定义:
- 结点的颜色非红即黑
- 根结点的颜色必须是黑色的
- 如果某个结点为红色,则它的孩子节点必须是黑色的。
- 表明从每个叶子到根的所有路径上不能有两个连续的红色节点。
- 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
- 所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。
红黑树的判断:
- 根结点是否为黑色。
- 每条路径的黑色节点相等。统计出一条路径的黑色节点的个数,然后与其他路径黑色节点个数进行比较。
- 不存在连续的红色节点,判断红色节点的孩子节点是否为红色。
代码:
#include <cstdio> #include <algorithm> using namespace std; #define BLACK 1 #define RED 0 struct Node{ int val; int color; Node *lchild,*rchild; Node(int v){ val=v>0?v:-v; color=v>0?BLACK:RED; lchild=rchild=nullptr; } }; void insert(Node* &root,int val) { if(root==nullptr){ root=new Node(val); return; } if(abs(val)<root->val) insert(root->lchild,val); else insert(root->rchild,val); } //深度遍历,计算黑色结点的个数以及判断是否会出现连续两个红色结点 int totalBlackCnt=0; bool flag=true; void dfs(Node* root,int cnt) { if(root==nullptr){ if(cnt!=totalBlackCnt) flag=false; return; } if(root->color==BLACK) cnt++; else{ if(root->lchild && root->lchild->color==RED) flag=false; if(root->rchild && root->rchild->color==RED) flag=false; } //printf("val:%d color:%d cnt:%d ",root->val,root->color,cnt); dfs(root->lchild,cnt); dfs(root->rchild,cnt); } int main() {int k,n,val; scanf("%d",&k); while(k--){ scanf("%d",&n); Node* root=nullptr; for(int i=0;i<n;i++){ scanf("%d",&val); insert(root,val); } if(root->color==RED){ printf("No "); continue; } totalBlackCnt=0;//记录从根结点到任意一个叶结点的简单路径上黑色结点的个数 //此处计算最左端的路径 Node* p=root; while(p){ if(p->color==BLACK) totalBlackCnt++; p=p->lchild; } flag=true;//初始化 dfs(root,0); printf("%s ",flag?"Yes":"No"); } return 0; }
【疑问】
按照我自己的想法,dfs()函数我是这么写的,然而这么写会有两个测试点通不过!还没搞清楚!!!
void dfs(Node* root,int cnt) { if(root==nullptr) return; if(root->color==BLACK) cnt++; else{ if(root->lchild && root->lchild->color==RED) flag=false; if(root->rchild && root->rchild->color==RED) flag=false; } if(root->lchild==nullptr && root->rchild==nullptr){ if(cnt!=totalBlackCnt) flag=false; } //printf("val:%d color:%d cnt:%d ",root->val,root->color,cnt); dfs(root->lchild,cnt); dfs(root->rchild,cnt); }
以上是关于1135 Is It A Red-Black Tree的主要内容,如果未能解决你的问题,请参考以下文章
PAT 1135. Is It A Red-Black Tree
PAT 1135 Is It A Red-Black Tree[难]
1135 Is It A Red-Black Tree(30 分)
1135 Is It A Red-Black Tree (30 分)