PAT甲级1135 【Is It A Red-Black Tree】(30)

10 篇文章 0 订阅
5 篇文章 0 订阅

2019.2.18更新:过了小半年连红黑树的基础是BST树都忘了。。即已知BST树的先序遍历可以重建这颗树。重建树记得加上引用&

判断条件包括:

1. 根结点是黑的

2. 红结点的孩子是黑的

3. For each node, all simple paths from the node to descendant leaves contain the same number of black nodes.

分析:一些判断题都是纸老虎,(不要被红黑树吓到了,你越觉得概念非常难的题考试的时候可能不会考那么难,至少没有叫你实现红黑树哈哈哈哈),其实这种题有点像根据题意进行模拟,先用先序建立BST,注意负号代表红色,而后用bfs遍历每个结点,并判断当前结点是否满足要求。PS:一次过非常的开心

更新代码:

#include<bits/stdc++.h>
using namespace std;
bool  isRedBlackTree;
int totalCount = -1;
struct Node {
	int val, neg;
	struct Node *left, *right;
};
vector<int> pre;
void insert(Node* &root, int val) {
	if(!root) {
		root = new Node();
		root->val = abs(val);
		root->neg = val < 0 ? 1 : 0;
		root->left = root->right = NULL;
	} else {
		if(root->val > abs(val)) {
			insert(root->left, val);
		} else {
			insert(root->right, val);
		}
	}
}
void checkDfsPath(Node* root, int countBlack) {
	if(!isRedBlackTree) return;
	if(!root) {
		if(totalCount == -1) {
			totalCount = countBlack;
		} else {
			if(totalCount != countBlack) {
				isRedBlackTree = false;
			}
		}
		return;
	}
	if(!root->neg) countBlack++;
	checkDfsPath(root->left, countBlack);
	checkDfsPath(root->right, countBlack);
}
void preOrderT(Node* root) {
	if(!isRedBlackTree) return;
	if(!root) return;
	if(root->neg) {
		if(root->left && root->left->neg) {
			isRedBlackTree = false;
		} else if(root->right && root->right->neg) {
			isRedBlackTree = false;
		}
	}
	totalCount = -1;
	checkDfsPath(root, 0);
	preOrderT(root->left);
	preOrderT(root->right);
}
int main() {
//	freopen("in.txt", "r", stdin);
	int K, N, temp;
	cin >> K;
	for(int i = 0; i<K; i++) {
		cin >> N;
		Node *root = NULL;
		for(int j = 0; j<N; j++) {
			cin >> temp;
			insert(root, temp);
		}
		isRedBlackTree = root->neg ? false : true;
		preOrderT(root); 
		isRedBlackTree ? cout << "Yes\n" : cout << "No\n";
	}
	
	return 0;
}

原来代码:

#include<stdio.h>
#include<stdlib.h>
#include<queue>
using namespace std;

typedef struct Tree{
	int val, neg;
	struct Tree *l, *r;
}Tree;

int abs(int num){
	if(num < 0) num = -num;
	return num;
}
int isRedBlackTree = 1, first = 0, cnt = 0;
Tree *insert(Tree *root, int val){
	if(root == NULL) {
		root = (Tree *)malloc(sizeof(Tree));
		root->val = abs(val);
		if(val < 0) root->neg = 1;
		root->l = root->r = NULL;
		return root;
	}
	if(root->val > abs(val)){
		root->l = insert(root->l, val);
	}
	else root->r = insert(root->r, val);
	return root;
}
void dfsPath(Tree *root, int sum){
	if(root == NULL){
		if(!first){
			first = 1;
			cnt = sum;
		}
		else {
			if(cnt != sum) isRedBlackTree = 0;
		}
		return ;
	}
	if(root->neg != 1) sum++;
	dfsPath(root->l, sum);
	dfsPath(root->r, sum);
}
void bfs(Tree *root){
	queue<Tree *> q;
	q.push(root);
	if(root->neg == 1) isRedBlackTree = 0;
	while(isRedBlackTree && !q.empty()){
		Tree *cur = q.front();
		q.pop();
		first = 0;
		dfsPath(cur, 0);
		if(cur->l) q.push(cur->l);
		if(cur->r) q.push(cur->r);
		if(cur->neg == 1) {
			if(cur->l && cur->l->neg == 1)  isRedBlackTree = 0;
			if(cur->r && cur->r->neg == 1)  isRedBlackTree = 0;
		}
	}
	if(isRedBlackTree) printf("Yes\n");
	else printf("No\n");
}
int main(){
	//freopen("in.txt", "r", stdin);
	int n, i, T, num;
	scanf("%d", &T);
	while(T--){
		isRedBlackTree = 1;
		Tree *root = NULL;
		scanf("%d", &n);
		for(i = 0; i<n; i++){
			scanf("%d", &num);
			root = insert(root, num);
		}
		bfs(root);
	}
	
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值