PAT甲级-1135 Is It A Red-Black Tree

主要是要理解红黑树的定义:

There is a kind of balanced binary search tree named red-black tree in the data structure. It has the following 5 properties:
(1) Every node is either red or black.
(2) The root is black.
(3) Every leaf (NULL) is black.
(4) If a node is red, then both its children are black.
(5) For each node, all simple paths from the node to descendant leaves contain the same number of black nodes.

翻译:

(1)红黑树的节点只能为红或者黑。
(2)根节点是黑。
(3)null为黑,表示叶子节点(没有child的节点为叶子节点)可以为红为黑。如果条件改为null节点为红,则叶子节点必须为黑。
(4)如果该节点为红,其child节点都为黑。
(5)每个节点到叶子节点的路径上的black节点数都相等。其实这跟从根节点到叶子节点的每条路径上的总black节点数都相等是一个意思,想一下就能理解。


所以这题,只需判断:

1. 根节点是否为黑。

2. 每个红节点的所有child是否都为黑。

3. 根节点到每个叶子节点的路径上的黑节点数是否都相等。

#include <bits/stdc++.h>
using namespace std;
typedef struct node {
	int key;
	struct node *left;
	struct node *right;
} Node, *Tree;
int T, N;
Node* tree_create(int key) {
//	Node *p = (Node *)malloc(sizeof(Node));
	Node *p = new Node();
	p->key = key;
	p->left = NULL;
	p->right = NULL;
	return p;
}
Node* tree_insert(Node *tree, int key) {
	if(tree == NULL) {
		tree = tree_create(key);
	}
	else if(abs(key) < abs(tree->key)) {
		tree->left = tree_insert(tree->left, key);
	}
	else if(abs(key) > abs(tree->key)) {
		tree->right = tree_insert(tree->right, key);
	}
	return tree;
}
int flag, reals;
bool red_jg(Node *tree, int cnt) {
	if(tree == NULL) {
		if(reals == -1) {
			reals = cnt;
		}
		else if(reals != cnt){
			flag = 0;
		}
		return true;
	}
	if(tree->key < 0) {
		if(tree->left && tree->left->key < 0) {
			return false;
		}
		if(tree->right && tree->right->key < 0) {
			return false;
		}
	}
	int tmp = tree->key > 0 ? 1 : 0;
	if(!red_jg(tree->left, cnt+tmp)) {
		return false;
	}
	if(!red_jg(tree->right, cnt+tmp)) {
		return false;
	}
	return true;
}
int judge(Node *tree) {
	if(tree->key < 0) {
		return 0;
	}
	if(!red_jg(tree, 0)) {
		return 0;
	}
	return flag;
}
void Free(Node *tree) {
	if(tree->left) {
		Free(tree->left);
	}
	if(tree->right) {
		Free(tree->right);
	}
	delete tree;
//	free(tree);
	tree = NULL;
}
int main() {
	scanf("%d", &T);
	for(int _ = 1; _ <= T; ++_) {
		scanf("%d", &N);
		flag = 1, reals = -1;
		Tree root = NULL;
		for(int i = 1; i <= N; ++i) {
			int key;
			scanf("%d", &key);
			root = tree_insert(root, key);
		}
		if(judge(root)) {
			printf("Yes\n");
		}
		else {
			printf("No\n");
		}
		Free(root);
	}
	return 0;
}


另外补充c的free和c++的delete的区别:

delete 用于释放new分配的内存,和new成对调用
free 用于释放malloc分配的内存,和malloc成对调用
使用free释放时需要判断指针是否为NULL,delete不用
free 释放内存,但不调用对象的析构函数
delete 不仅释放内存,还调用对象的析构函数
delete 和new是对对象的操作,是运算符
free 和malloc是对内存空间的操作


继续加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值