以前没接触过这种树,看了别人的代码,加上了详细的注释。
思路全在注释中。
简单把红黑树的五条性质翻译下:
1.每个节点只有两种颜色:非红即黑;
2.根节点是黑色;
3.叶子节点(NULL)是黑色的(对于每个叶子节点来说,他的左右孩子(NULL)都是黑的)
4.若节点为红色,他的所有孩子都是黑色;
5.对于每个节点,从这个节点到每个叶子节点的黑色节点的个数都相同。
我将测试样例放上,以便复制。
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
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 bool isRBTree = true;//默认所有的树全为红黑树 5 int lastNum = -1;//这个是第五点,因为要比较树的不同分支上黑节点的个数,所以要记录上一个树黑点的个数, 6 //但是第一次记录时是没有上一个树的数据的,所以要去判断是不是第一次记录,用初始化为-1的方式来标记 7 8 struct Node 9 { 10 int data; 11 bool isblack;//是否为黑点 12 Node *lchild ;//左右孩子默认都为空 13 Node *rchild; 14 15 void setData(int mdata) 16 { 17 if (mdata > 0)//如果数据大于0 18 { 19 isblack = true;//黑 20 } 21 else 22 isblack = false;//否则为红 23 data = abs(mdata);//将绝对值存入,因为红黑已经记录,符号已经没有意义 24 } 25 }; 26 27 Node *Insert(int a, Node *root) 28 { 29 if (root == NULL)//如果为空 30 { 31 root = (Node *)malloc(sizeof(Node)); 32 root->lchild = NULL;//设置节点的左右孩子为null 33 root->rchild = NULL; 34 root->setData(a); 35 return root; 36 } 37 if (abs(a) < root->data)//红黑树的左孩子一定比父亲小 38 { 39 root->lchild = Insert(a, root->lchild);//插入 40 } 41 else //右孩子一定比父亲大 42 root->rchild = Insert(a, root->rchild); 43 return root; 44 } 45 46 void DFS(Node *node, int count) 47 { 48 if (!isRBTree)//如果已经判断出不是红黑树 49 { 50 return;//退出 51 } 52 if (node == NULL)//如果是空节点有两种情况 53 { 54 if (lastNum == -1)//一种是还没进行第一次遍历 55 { 56 lastNum = count;//那么就要将计数器归零,也就是在main里面传进来的0 57 } 58 else if (lastNum != count)//如果是已经遍历到叶子结点, 59 //换句话说就是节点的左孩子或者右孩子为空 60 { 61 isRBTree = false;//因为本次遍历与上次遍历的黑节点数不同,不符合第五点 62 //所以返回假 63 } 64 return;//遍历到终点,结束遍历 65 } 66 if (node->isblack)//如果这个点是黑节点 67 { 68 count++; 69 } 70 else 71 { 72 if (node->lchild && !node->rchild->isblack)//左孩子存在并且他的左孩子是红的,第4点 73 isRBTree = false;//为假 74 if (node->rchild && !node->rchild->isblack)//同理 75 isRBTree = false; 76 } 77 DFS(node->lchild, count);//深度搜索左孩子 78 DFS(node->rchild, count); 79 80 } 81 82 int main() 83 { 84 int num; 85 scanf("%d", &num); 86 bool answer[33];//将答案存在数组中 87 int i, j; 88 for (i = 0; i < num; i++) 89 { 90 int number; 91 scanf("%d", &number); 92 Node *root = NULL; 93 int a; 94 for (j = 0; j < number; j++) 95 { 96 scanf("%d", &a); 97 root = Insert(a, root); 98 } 99 isRBTree = root->isblack;//条件2 100 lastNum = -1;//好多样例,记得初始化 101 DFS(root, 0); 102 answer[i] = isRBTree; 103 isRBTree = true;//初始化,和上面一样 104 } 105 for (i = 0; i < num; i++) 106 { 107 if (answer[i]) 108 printf("Yes\n"); 109 else 110 printf("No\n"); 111 } 112 }