题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805346063728640
红黑树满足二叉查找树的性质,左小于根,根小于右。
红黑树的特性:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从任一节点到其每个叶子节点(NULL)的所有简单路径都包含相同数目的黑色节点。
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 using namespace std; 5 6 struct Node { 7 int data; 8 Node* lchild; 9 Node* rchild; 10 }; 11 const int maxn = 50; 12 vector<int> pre,in; 13 14 Node* create(int preL,int preR,int inL,int inR) { //先序和中序遍历二叉树 15 if(inL > inR) return NULL; 16 Node* node = new Node; 17 node->data = pre[preL]; 18 int k,leftNum; 19 for(k = inL; k <= inR; ++k) if(in[k] == abs(pre[preL])) break; 20 leftNum = k-inL; 21 node->lchild = create(preL+1,preL+leftNum,inL,k-1); 22 node->rchild = create(preL+leftNum+1,preR,k+1,inR); 23 return node; 24 } 25 26 bool judge1(Node* root) { //判断性质4 27 if(root == NULL) return true; 28 if(root->data < 0) { 29 if(root->lchild != NULL&& root->lchild->data < 0) return false; 30 if(root->rchild != NULL&& root->rchild->data < 0) return false; 31 } 32 return judge1(root->lchild)&&judge1(root->rchild); 33 } 34 35 int getNum(Node* root) { //后序遍历,求当前二叉树的高度 36 if(root == NULL) return 0; 37 int l = getNum(root->lchild); 38 int r = getNum(root->rchild); 39 return root->data>0?max(l,r)+1:max(l,r);//如果是黑色结点,高度加一 40 } 41 42 bool judge2(Node* root) { //判断性质5 43 if(root == NULL) return true; 44 int l = getNum(root->lchild); 45 int r = getNum(root->rchild); 46 if(l!=r) return false; 47 return judge2(root->lchild)&&judge2(root->rchild); 48 } 49 int main() { 50 int k,n; 51 cin>>k; 52 while(k--) { 53 cin>>n; 54 pre.resize(n); 55 in.resize(n); 56 for(int i = 0; i < n; ++i) { 57 cin>>pre[i]; 58 in[i] = abs(pre[i]); 59 } 60 sort(in.begin(),in.end()); 61 Node* root = create(0,n-1,0,n-1); 62 if(pre[0] < 0 || !judge1(root) || !judge2(root)) printf("No\n");//判断性质2、4、5 63 else printf("Yes\n"); 64 } 65 return 0; 66 }