主要是要理解紅黑樹的定義:
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是對內存空間的操作
繼續加油~