A1135 Is It A Red-Black Tree(红黑树)

题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805346063728640

思路很清晰,首先根据先序遍历建立二叉搜索树,然后判断即可,主要是依据规则2、4、5。

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include<stack>
#include<queue>
#include<sstream>
using namespace std;

/*
A1135 Is It A Red-Black Tree (30 分)
*/

typedef struct node* Tree;
struct node {
	int key;
	Tree Lchild=NULL;
	Tree Rchild=NULL;
	int black_num = -1;		//从该结点到叶子结点黑色结点的数量\
							初始化-1-2代表左右孩子到叶子结点黑色结点的数量不同
};

void Insert(Tree &root, int key) {//其实不用加引用
	if (root == NULL)
	{
		root = new node;
		root->Lchild = root->Rchild = NULL;
		root->key = key;
		return;
	}

	if (labs(key) > labs(root->key))	//这里加绝对值
		Insert(root->Rchild, key);
	else
		Insert(root->Lchild, key);
}

void Delete(Tree& root) {
	if (root == NULL)
		return;
	Delete(root->Lchild);
	Delete(root->Rchild);

	free(root);
}

bool Judge_black(Tree root) {
	if (root == NULL)
		return true;
	else if (root->key > 0)
		return true;
	else
		return false;
}

//计算某个结点到从该结点到叶子结点黑色结点的数量\
初始化-1-2代表左右孩子到叶子结点黑色结点的数量不同
int Cal_black(Tree &root) {
	if (root == NULL)
		return 1;
	if (root->black_num == -2) {	//不用计算了,不是红黑树
		return -2;
	}

	int LB=Cal_black(root->Lchild);
	if (LB == -2) return -2;
	int RB = Cal_black(root->Rchild);
	if (RB == -2 || LB!=RB) return -2;

	if (Judge_black(root))
		root->black_num = LB + 1;
	else
		root->black_num = LB;

	return root->black_num;
}

//判断是否为红黑树
bool Judge(Tree root) {
	//Part 2: The root is black.
	if (Judge_black(root) == false)
		return false;
	//part 4: Use LevelOrder to judge.( If a node is red, then both its children are black)
	queue<Tree> q;
	if(root!=NULL)
		q.push(root);
	while (!q.empty()) {
		Tree T_node = q.front();
		q.pop();
		if (T_node->Lchild != NULL) q.push(T_node->Lchild);
		if (T_node->Rchild != NULL) q.push(T_node->Rchild);

		if (T_node->key < 0) {
			if (Judge_black(T_node->Lchild)==false || Judge_black(T_node->Rchild)==false)
				return false;
		}
	}

	//Part 5: For each node, all simple paths from the node \
	to descendant leaves contain the same number of black nodes.
	if (Cal_black(root) == -2) return false;

	return true;

}

int main() {

	//freopen("input.txt", "r", stdin);

	int K, N;	//K is the total number of cases. N is the total number of nodes
	cin >> K;
	for (int i1 = 0; i1 < K; i1++) {
		cin >> N;
		Tree root = NULL;
		for (int i2 = 0; i2 < N; i2++) {
			int temp;
			cin >> temp;
			Insert(root, temp);
			
		}
		if (Judge(root) == true)
			cout << "Yes\n";
		else
			cout << "No\n";

		Delete(root);
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值