先简单陈述一下题目,先给一个总个数,之后给一个数节点个数和这个树的前序遍历,最后让输出这个数是不是红黑树
红黑树要求
1.根节点为黑
2.叶子(NULL)为黑
3.红点的儿子为黑
4.每一个节点左右树下面黑点数量必须同
其实一看只给前序遍历有点慌,但是勿慌,因为这是平衡二叉树,所以完全可以根据连续遍历然后往里面插入数据,直接建树
最后卡在了怎么计算左右树中的黑点上,最后参考了网上才过的,不得不说自己还需努力啊
int n, s = -1;
bool pan = true;
struct no {
int n;
no *l;
no *r;
int rn;
int ln;
};
struct no* inst(int s,no *head)
{
if (head==NULL)
{
head = (struct no*)malloc(sizeof(no));
head->n = s;
head->l = NULL;
head->r = NULL;
if (head->n > 0)
{
head->ln = 1;
head->rn = 1;
}
else
{
head->ln = 0;
head->rn = 0;
}
}
else
{
if (abs(s) <= abs(head->n))
head->l = inst(s, head->l);
else
head->r = inst(s, head->r);
}
return head;
}
void search(no *root)
{
if(root->l!=NULL)
search(root->l);
if (root->r != NULL)
search(root->r);
if (pan == false)
return;
if (root->n < 0 && ((root->l != NULL&&root->l->n < 0) || (root->r != NULL&&root->r->n < 0))) //判断红点的子节点为黑
{
pan = false;
return;
}
if (root->n > 0) //计算每个点左右的黑点是否相等
{
if (root->l == NULL) //到头置为一
root->ln = 1;
else
root->ln = root->l->ln + 1; //否则则等于下面的个数加1
if (root->r == NULL)
root->rn = 1;
else
root->rn = root->r->rn + 1;
}
if (root->n < 0)
{
if (root->l == NULL)
root->ln = 0;
else
root->ln = root->l->ln;
if (root->r == NULL)
root->rn = 0;
else
root->rn = root->r->rn;
}
if (root->ln != root->rn)
{
pan = false;
return;
}
}
int main(void)
{
int num;
scanf("%d", &num);
for (int h = 0;h < num;h++)
{
int i, j;
scanf("%d", &n);
struct no *head=NULL;
pan = true;
for (i = 0;i < n;i++) //虽然这个题只给出了前序遍历,但是因为是平衡二叉树,所以直接按输入顺序建树即可
{
int s;
scanf("%d", &s);
head=inst(s,head);
}
if (head->n < 0)
{
printf("No\n");
continue;
}
search(head);
if (pan == false)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}