题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805346063728640
题意:
给定一棵二叉搜索树的先序遍历结果,问这棵树是不是一棵红黑树。
思路:
首先需要明确二叉搜索树和红黑树的性质。
二叉搜索树的每个节点,左子树上的值都比这个节点的值小,右子树上的值都比这个节点的值大。
因此对于一棵二叉搜索树,如果给定了先序遍历结果,就可以唯一确定这棵树了。
红黑树的性质:
1、每个节点是红色或是黑色
2、根节点是黑色的
3、红色节点的儿子一定是黑色的
4、从任意节点到NULL指针的每一条路径的黑色节点数都是相同的
对于这道题,首先我们可以唯一的建树
然后在这棵唯一的树上进行dfs,判断当前节点的左右子树是否是一棵红黑树。边界条件显然是当节点只有一个或没有儿子的时候,此时直接判断。
【啊已经四月了!来不及了!】
1 #include<cstdio> 2 #include<cstdlib> 3 #include<map> 4 #include<set> 5 #include<iostream> 6 #include<cstring> 7 #include<algorithm> 8 #include<vector> 9 #include<cmath> 10 #include<stack> 11 #include<queue> 12 13 #define inf 0x7fffffff 14 using namespace std; 15 typedef long long LL; 16 typedef pair<string, string> pr; 17 18 int k, n; 19 const int maxn = 35; 20 struct node{ 21 int val; 22 bool isred; 23 int lchild, rchild; 24 }nodes[maxn]; 25 26 int tot = 0; 27 void addnode(int val) 28 { 29 if(val < 0){ 30 nodes[tot].isred = true; 31 val = -val; 32 } 33 else{ 34 nodes[tot].isred = false; 35 } 36 nodes[tot].val = val; 37 nodes[tot].lchild = nodes[tot].rchild = -1; 38 39 int now = 0, prev = 0; 40 while(now != -1){ 41 prev = now; 42 if(val > nodes[now].val){ 43 now = nodes[now].rchild; 44 } 45 else{ 46 now = nodes[now].lchild; 47 } 48 } 49 if(val > nodes[prev].val){ 50 nodes[prev].rchild = tot++; 51 } 52 else{ 53 nodes[prev].lchild = tot++; 54 } 55 } 56 57 bool flag = true; 58 int dfs(int rt) 59 { 60 int l = nodes[rt].lchild, r = nodes[rt].rchild; 61 int lres = 0, rres = 0; 62 if(l != -1){ 63 if(dfs(l) == -1)return -1; 64 lres += dfs(l); 65 } 66 if(r != -1){ 67 if(dfs(r) == -1)return -1; 68 rres += dfs(r); 69 } 70 if(l == -1 && r == -1){ 71 return !nodes[rt].isred; 72 } 73 if(lres != rres){ 74 return -1; 75 } 76 if(nodes[rt].isred && (nodes[l].isred || nodes[r].isred)){ 77 return -1; 78 } 79 return lres + !nodes[rt].isred; 80 } 81 82 void printTree(int rt) 83 { 84 if(rt == -1)return; 85 printf("%d ", nodes[rt].val); 86 printTree(nodes[rt].lchild); 87 printTree(nodes[rt].rchild); 88 } 89 90 int main() 91 { 92 scanf("%d", &k); 93 while(k--){ 94 for(int i = 0; i <= tot; i++){ 95 nodes[tot].val = 0; 96 nodes[tot].isred = 0; 97 nodes[tot].lchild = nodes[tot].rchild = -1; 98 } 99 tot = 0; 100 flag = true; 101 scanf("%d", &n); 102 scanf("%d", &nodes[tot].val); 103 nodes[tot].isred = false; 104 nodes[tot].lchild = nodes[tot].rchild = -1;tot++; 105 for(int i = 1; i < n; i++){ 106 int val; 107 scanf("%d", &val); 108 addnode(val); 109 } 110 111 //printTree(0); 112 if(nodes[0].val < 0){ 113 printf("No "); 114 } 115 else{ 116 if(dfs(0) != -1){ 117 printf("Yes "); 118 } 119 else{ 120 printf("No "); 121 } 122 } 123 } 124 return 0; 125 }