根据给定的二叉搜索树,判断是否是红黑树。
符合红黑树的条件:
1.、节点是红色或黑色。
2、根节点是黑色。
3、 每个叶子节点(NULL节点,空节点)是黑色的。
4、 一个节点是红色,其左右子树为黑色
5、 对于树上任何节点来说,其左右子树的黑色节点个数是一样。
这里主要判断的条件有三个:
1、根是黑色(第二个测试点)
2、一个节点是红色,其左右子树为黑色。
3、对于树上任何节点来说,其左右子树的黑色节点个数是一样。
二叉搜索树左小右大,这一题可以直接根据这个性质和先序遍历的元素,重新进行先序遍历建立树,其实不需要建树,直接进行判断,根据父节点是否红色和当前节点是否红色判断是否符合条件;根据得到的左右子树的高度判断是否相同判断是否符合条件,右节点是当前节点找到第一个比当前节点大的节点。高度是黑色颜色的个数,如果是红色叶子节点,返回0,是黑色叶子节点返回1,然后根据每个节点的颜色从下到上处理。
这一题一开始题目理解错误,以为红黑树是从根节点出发每条路径的黑色节点个数的一样就行了。后来,改正后一直只有24分,第二个测试点总是通不过,搜索后发现别人说根节点要是黑色,修改后才通过,一直没有注意到这一点。
写过这一题,才算对红黑树有了一点的理解,它是用路径上的黑色节点个数当做高度,用于平衡。
(用时:2:05:15.26)
#include <bits/stdc++.h>
using namespace std;
const int RED = 0;
const int BLACK = 1;
bool isRBTree = true;
int bulidTree(int preOrder[],int currentIndex,int right,int fatherColor)
{
if(right<=currentIndex) {
return 0;
}
int currentColor = BLACK;
if(preOrder[currentIndex]<0) {
currentColor = RED;
if(fatherColor == RED) {
isRBTree = false;
}
}
int value = preOrder[currentIndex] < 0 ? -preOrder[currentIndex] :preOrder[currentIndex];
int rightIndex = -1;
int leftIndex = -1;
for(int i=currentIndex+1; i<right; i++) {
if(value < preOrder[i]||value < -preOrder[i]) {
rightIndex = i;
break;
}
//有相同值的,这里是默认当做一个节点,这一点这一题没有测试
else if(value ==preOrder[i]||value == -preOrder[i] ){
leftIndex = i;
}
}
if(rightIndex == -1) {
rightIndex = right;
}
if(leftIndex==-1){
leftIndex = currentIndex + 1;
}
else{
leftIndex++;
}
int leftHigh = leftIndex==rightIndex? currentColor: bulidTree(preOrder,leftIndex,rightIndex,currentColor) +currentColor;
int rightHigh = rightIndex == right? currentColor: bulidTree(preOrder,rightIndex,right,currentColor) + currentColor;
if(leftHigh != rightHigh) {
isRBTree = false;
}
int treeHigh = leftHigh > rightHigh ? leftHigh : rightHigh;
return treeHigh ;
}
int main()
{
int n,m,k;
scanf("%d",&k);
for(int i=0; i<k; i++) {
scanf("%d",&n);
int preOrder[n];
for(int i=0; i<n; i++) {
scanf("%d",&preOrder[i]);
}
isRBTree = true;
bulidTree(preOrder,0,n,BLACK);
if(preOrder[0]<0){
isRBTree =false;
}
if(isRBTree) {
printf("Yes\n");
} else {
printf("No\n");
}
}
return 0;
}