题意:
给你一个树的先序遍历,让你判断是否为red-black tree. 另外告诉你是一个二叉查找树(BST)。
思路:
先说一下什么是红黑树:
红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能.
红黑树是一种平衡二叉树,但并不是完美的平衡二叉树,也就是并不满足左右深度绝对值差1,所以这里我们无需判断是否平衡.
红黑树的性质:
1.节点可以是黑的或红的
2.根节点一定是黑的
3.所有叶节点是黑的.(注意这里的叶节点是NIL结点)
4.如果一个结点时红的,那么他的子结点一定是黑的.
5.从任意结点到每个叶节点的简单路径上经过黑色结点的个数相同.
所以这个题目我们根据先序遍历,利用BST树的性质建树即可.然后爆搜判断一下就好了.性质5可以转化为直接从根节点开始到每个叶节点的黑色结点个数相同.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 50;
struct node
{
int val,col;
node *l;
node *r;
node()
{
l = r = nullptr;
}
};
int n,flag;
node *Insert(node *root,int val)
{
if(root == nullptr)
{
node *tmp = new node;
tmp -> val = abs(val);
tmp -> col = val > 0 ? 1:0;
return tmp;
}
if(abs(val) < root -> val)
root -> l = Insert(root -> l,val);
else
root -> r = Insert(root -> r,val);
return root;
}
//vector<int>vt;
int num,leaf ;
void dfs(node *root,int s)
{
if(flag == 0) return ;
if(root == nullptr)
{
if(num == -1) num = s;
else if(num != s) flag = 0;
return ;
}
if(root -> col == 1) s++;
else
{
if(root -> l && root -> l -> col == 0) flag = 0;
if(root -> r && root -> r -> col == 0) flag = 0;
}
dfs(root -> l,s);
dfs(root -> r,s);
return ;
}
int main()
{
int _;
cin >>_;
while(_--)
{
//vt.clear();
flag = 1;
leaf = 0;
num = -1;
scanf("%d",&n);
node *root = nullptr;
for(int i = 1;i <= n;++i)
{
int x;
scanf("%d",&x);;
root = Insert(root,x);
}
if(root -> col == 0)
{
puts("No");
continue;
}
dfs(root,0);
if(flag)
puts("Yes");
else
puts("No");
}
return 0;
}