A1135
个人思路
本题考查树的构建+树的遍历(理解题目要求时关键)
总体来说就是根据题目给的条件来判断二叉树是否为红黑树
首先看了大佬博客之后才知道,红黑树和二叉平衡树(AVL)是两码事,红黑树的平衡因子并不是1
判断依据:
- 根节点为黑色
- 红节点的子节点均为黑色
- 任意节点到其各个叶子节点的路径中,黑节点的个数相同
- PS:除了红节点就是黑节点无需判断,每个叶子节点(空节点)为黑色(这个条件我没明白,很明显Figure1叶子节点是红色啊,但这个条件也不用判断)
解题思路:
- 由于红黑树是查找树,可以根据pre[]来构建
- pre[0]即为根节点,轻松判断颜色
- bfs可以快速判断某个节点的子节点颜色
- dfs可以快速判断路径中黑节点的个数
个人错误的dfs代码(dfs用的还是不够老练啊)
int optStep;
bool isfirst = true;
void dfs(int root, int step, bool &flag)
{
if(nodes[root].left == -1 && nodes[root].right == -1)
{
if(isfirst == true)//第一条路径
{
optStep = step;
isfirst = false;
}
else
{
if(step != optStep)
flag = false;
}
return;
}
if(nodes[root].isred == false)//统计黑节点
{
step++;
}
if(nodes[root].left != -1)
{
dfs(nodes[root].left, step, flag);
if(nodes[root].isred == false)//统计黑节点
{
step--;
}
}
if(nodes[root].right != -1)
{
dfs(nodes[root].right, step, flag);
if(nodes[root].isred == false)//统计黑节点
{
step--;
}
}
}
for(int i = 0; i < 35; ++i)
{
int step = 0;
bool flag = true;
if(nodes[i].data != 0)
{
root = i;
optStep = 0;
isfirst = true;
dfs(root, step, flag);
if(flag == false)
{
istree == false;
break;
}
}
}
本题思路
- 因为是多次查询,注意一些变量的初始化
- 如果把dfs,放在bfs中效果会更好(直接可以对所有节点进行遍历)
AC代码
#include <bits/stdc++.h>
using namespace std;
int K;
int pre[35];
bool istree;//判断是否为红黑树
struct Node{
int data;
int left, right;
bool isred;
Node(){}
Node(int dd, int ll, int rr)
{
data = dd;
left = ll;
right = rr;
}
}nodes[35];
int pos;
int newNode(int x)
{
nodes[pos] = Node(abs(x), -1, -1);
if(x < 0)
nodes[pos].isred = true;
else
nodes[pos].isred = false;
return pos++;
}
void insert(int &root, int x)
{
int temp = abs(x);
if(root == -1)
{
root = newNode(x);
return;
}
if(nodes[root].data > temp)
{
insert(nodes[root].left, x);
}
else
{
insert(nodes[root].right, x);
}
}
bool levelOrder(int root)
{
queue<int> q;
q.push(root);
while(!q.empty())
{
int now = q.front();
q.pop();
//cout << nodes[now].data << " ";
int ll = nodes[now].left;
int rr = nodes[now].right;
bool rootisred = nodes[now].isred;
if(ll != -1)
{
q.push(ll);
if(rootisred == true && nodes[ll].isred == true)
return false;//判断红节点的子节点是否为黑节点
}
if(rr != -1)
{
q.push(rr);
if(rootisred == true && nodes[rr].isred == true)
return false;
}
}
return true;
}
int optStep = -1;
bool isfirst = true;
void dfs(int root, int step)
{
if(root == -1)
{
if(istree == true)
{
if(optStep == -1)
optStep = step;
else if(optStep != step)
istree = false;
}
return;
}
if(nodes[root].isred == false)//统计路径上黑节点个数
step++;
dfs(nodes[root].left, step);
dfs(nodes[root].right, step);
}
int main(int argc, char *argv[]) {
scanf("%d", &K);
while(K--)
{
int N;
//初始化的问题!!!
istree = true;//是否是红黑树
scanf("%d", &N);
int root = -1;//初始化根节点
memset(pre, 0, sizeof(pre));
pos = 0;
for(int i = 0; i < 35; ++i)
{
nodes[i] = Node(0, 0, 0);
}
for(int i = 0; i < N; ++i)
{
scanf("%d", &pre[i]);
insert(root, pre[i]);
}
if(pre[0] < 0)//根节点不为黑色
{
printf("No\n");
continue;
}
istree = levelOrder(root);
if(istree == false)
{
printf("No\n");
continue;
}
for(int i = 0; i < N; ++i)
{
optStep = -1;//初始化的问题!!!
dfs(i, 0);
if(istree == false)
break;
}
if(istree == false)
{
printf("No\n");
continue;
}
printf("Yes\n");
}
return 0;
}