PAT甲组1135 Is It A Red-Black Tree思路解析和代码

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值