#include <iostream>
#define NULLVAL -1
using namespace std;
bool BLACK = true;
bool RED = false;
class RBTree {
public:
RBTree* left;
RBTree* right;
float val;
bool color;
RBTree* parent;
RBTree() {
left = NULL;
right = NULL;
val = NULLVAL;
color = BLACK;
parent = NULL;
}
RBTree(float value, bool colr) {
left = NULL;
right = NULL;
val = value;
color = colr || RED;
parent = NULL;
}
};
void PrintChilds(RBTree* node) {
if (node == NULL) {
cout << "node为NULL" << endl;
return;
}
if (node->parent != NULL) {
cout << "节点 " << node->val << "的父节点的值为: " << node->parent->val << " 颜色为: " << (node->parent->color ? "BLACK" : "RED") << endl;
} else {
cout << "节点 " << node->val << "的父节点值为空" << endl;
}
}
RBTree* setChildTree(RBTree* &node, char direct, float value, bool color) {
if (node == NULL) return NULL;
RBTree* child = new RBTree();
child->parent = node;
child->color = color;
child->val = value;
if(direct == 'r') node->right = child;
else node->left = child;
return child;
}
RBTree* ParentOf(RBTree* node) {
return (node == NULL) ? NULL : node->parent;
}
RBTree* UncleOf(RBTree* node) {
RBTree* father = ParentOf(node);
RBTree* grand = ParentOf(father);
if (grand == NULL) return NULL;
if (father == grand->left) {
return (grand->right == NULL) ? NULL : grand->right;
} else if (father == grand->right){
return (grand->left == NULL) ? NULL : grand->left;
} else {
return NULL;
}
}
void SetColor(RBTree* node, bool color) {
node->color = color;
}
RBTree* LeftChildOf(RBTree* node) {
if(node == NULL) return NULL;
return node->left;
}
RBTree* RightChildOf(RBTree* node) {
if(node == NULL) return NULL;
return node->right;
}
void LeftRotation(RBTree* &root, RBTree* node) {
if(node == NULL) return;
if(node->right == NULL) return;
RBTree* father = node->parent;
RBTree* nodeRight = node->right;
if (nodeRight->left == NULL) {
node->right = NULL;
} else {
node->right = nodeRight->left;
nodeRight->left->parent = node;
}
if(father == NULL) {
nodeRight->parent = NULL;
root = nodeRight;
} else {
nodeRight->parent = father;
if(father->left == node) {
father->left = nodeRight;
} else {
father->right = nodeRight;
}
}
nodeRight->left = node;
node->parent = nodeRight;
}
void RightRotation(RBTree* &root, RBTree* node) {
if(node == NULL) return;
if(node->left == NULL) return;
RBTree* father = node->parent;
RBTree* nodeLeft = node->left;
if(nodeLeft->right == NULL) {
node->left = NULL;
} else {
node->left = nodeLeft->right;
nodeLeft->right->parent = node;
}
if(father == NULL) {
nodeLeft->parent = NULL;
root = nodeLeft;
} else {
nodeLeft->parent = father;
if(father->left == node) {
father->left = nodeLeft;
} else {
father->right = nodeLeft;
}
}
node->parent = nodeLeft;
nodeLeft->right = node;
}
void InOrder(RBTree* root) {
if(root != NULL) {
InOrder(root->left);
PrintChilds(root);
InOrder(root->right);
}
}
void fixPosition(RBTree* root, RBTree* node) {
if(node == NULL) return;
if(node == root) return;
if(node->parent->color == BLACK) return;
while(node != NULL && node != root && node->parent->color == RED) {
if(UncleOf(node) == NULL) {
bool lr1, lr2;
lr1 = ParentOf(ParentOf(node))->left == ParentOf(node);
lr2 = ParentOf(node)->left == node;
if(lr1 && lr2) {
RightRotation(root, ParentOf(ParentOf(node)));
SetColor(ParentOf(node), BLACK);
SetColor(ParentOf(node)->right, RED);
} else if(lr1 && !lr2) {
LeftRotation(root, ParentOf(node));
RightRotation(root, ParentOf(node));
SetColor(node, BLACK);
SetColor(node->right, RED);
} else if(!lr1 && lr2) {
RightRotation(root, ParentOf(node));
LeftRotation(root, ParentOf(node));
SetColor(node, BLACK);
SetColor(node->left, RED);
} else {
LeftRotation(root, ParentOf(ParentOf(node)));
SetColor(ParentOf(node), BLACK);
SetColor(ParentOf(node)->left, RED);
}
} else {
SetColor(ParentOf(node), BLACK);
SetColor(UncleOf(node), BLACK);
SetColor(ParentOf(ParentOf(node)), RED);
node = ParentOf(ParentOf(node));
}
}
SetColor(root, BLACK);
}
void Insert(RBTree* root, float dat) {
if(root == NULL) {
root = new RBTree(dat, BLACK);
return;
}
RBTree* father = NULL;
RBTree* temp = root;
RBTree* nnode = NULL;
while(temp != NULL) {
father = temp;
if(dat < temp->val) {
temp = temp->left;
} else {
temp = temp->right;
}
}
if(dat < father->val) {
nnode = setChildTree(father, 'l', dat, RED);
} else {
nnode = setChildTree(father, 'r', dat, RED);
}
fixPosition(root, nnode);
}
int main() {
RBTree* root = new RBTree(7, BLACK);
setChildTree(root, 'l', 3, RED);
setChildTree(root, 'r', 10, RED);
setChildTree(root->left, 'l', 2, BLACK);
setChildTree(root->left, 'r', 5, BLACK);
setChildTree(root->right, 'l', 8, BLACK);
setChildTree(root->right, 'r', 11, BLACK);
setChildTree(root->left->left, 'l', 1, RED);
setChildTree(root->left->right, 'l', 4, RED);
setChildTree(root->left->right, 'r', 6, RED);
setChildTree(root->right->left, 'r', 9, RED);
setChildTree(root->right->right, 'r', 12, RED);
Insert(root, 0.5);
Insert(root, 1.5);
Insert(root, 4.5);
InOrder(root);
return 0;
}
- 原则
- 上黑下红(🌂)
- 新插入的节点必须是红色
- 一个红色节点的两个子节点必须是黑色
- 根节点是黑色节点
- 不能有连续的两个红色节点
- 注意附加情况中的递归问题(将此节点的爷爷节点 赋值给 此节点,while循环)
<一> 2-3-4树,2节点(单元素)对应红黑树的插入前图像

插入后的图象

<二> 2-3-4树,3节点(双元素)对应红黑树的插入前图象

插入后的图象

调整后的图象

<三> 2-3-4树,4节点(三元素)对应红黑树的插入前图象

插入后的图象

调整后的图象(父节点和叔叔节点变黑,爷爷节点变红)

需要递归的情况
- 调整完的图象如果是下边这种情况,需要递归
