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是對內存空間的操作


繼續加油~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章