红黑树的概念这里介绍一篇博主觉得很好的文章:
30张图带你彻底理解红黑树
然后这里给出一个在线生成红黑树动态图的网站:
https://www.cs.usfca.edu/~galles/visualization/RedBlack.html
然后给出我的环境:
clion + cmake:
代码实现:
//
// Created by anwuq on 2020/2/2.
//
//
// Created by anwuq on 2020/2/2.
//
#include "iostream"
#include "vector"
#include
#define red 0
#define black 1
#define BASEINDENT 30
#define max(a,b) a > b ? a : b
#define CVT(s) s ==1 ? "B" : "R"
typedef struct redblackTree {
int color;
int value;
redblackTree *left;
redblackTree *right;
redblackTree *father;
} RBNode,*lpRBNode;
void leftRotate(lpRBNode p){
// if(p->father!=NULL && p->right!=NULL){
if(p->right==nullptr)return;
if(p->father) {
if(p->father->left==p)p->father->left = p->right;
else if(p->father->right==p)p->father->right=p->right;
}
p->right->father = p->father;
p->father = p->right;
auto t = p->right->left;
p->right->left = p;
p->right = t;
if(t!=NULL) t->father = p;
}
void rightRotate(lpRBNode p){
// if(p->father!=NULL && p->left!=NULL){
if(p->left==nullptr)return;
if(p->father) {
if(p->father->left==p)p->father->left = p->left;
else if(p->father->right==p)p->father->right=p->left;
}
p->left->father = p->father;
p->father = p->left;
auto t =p->left->right;
p->left->right = p;
p->left = t;
if(t != nullptr)t->father=p;
}
void insert_fix(lpRBNode& p){
if(p->father == nullptr){
p->color = black;
return;
}
if(p->father->color == black){
return;
} else if(p->father->color== red){
lpRBNode pp = p->father->father;
if(pp->left && pp->left->color == red && pp->right && pp->right->color == red){
pp->left->color = black;
pp->right->color = black;
pp->color = red;
insert_fix(pp);
// 叔叔节点不存在或黑色
} else if (pp->left && p->father == pp->left &&
(pp->right == nullptr ||
(pp->right && pp->right->color == black))){
if(p == p->father->left){
p->father->color = black;
pp->color = red;
rightRotate(pp);
} else if(p == p->father->right){
leftRotate(p->father);
insert_fix(p->left);
}
} else if (pp->right && p->father == pp->right &&
(pp->left == nullptr ||
(pp->left && pp->left->color == black))) {
if(p == p->father->right) {
p->father->color = black;
pp->color = red;
leftRotate(pp);
} else if(p == p->father->left) {
rightRotate(p->father);
insert_fix(p->right);
}
}
}
}
void insert(lpRBNode& rbt,int node){
auto p = new RBNode;
p->color = red;
p->value = node;
p->left = nullptr;
p->right = nullptr;
p->father = nullptr;
// 插入情景一:树为空节点
if(rbt == nullptr){
rbt = p; // 指针指向同一位置
p->color = black;
return;
}
lpRBNode pp = rbt;
// 遍历到叶子节点
while (true){
if(p->value<pp->value){
if(pp->left==nullptr){
pp->left=p;
p->father = pp;
break;
}
else pp = pp->left;
}
else {
if(pp->right==nullptr){
pp->right=p;
p->father = pp;
break;
}
else pp=pp->right;
}
}
insert_fix(p);
lpRBNode top = p;
while (top->father!=nullptr){
top=top->father;
}
rbt = top;
}
lpRBNode build_rbt(std::vector<int>& nodes){
lpRBNode rbn;
rbn = nullptr;
for(auto node: nodes){
insert(rbn,node);
}
return rbn;
}
lpRBNode find(lpRBNode rbn,int node){
if(rbn == nullptr){
return nullptr;
}
if(rbn->value == node){
return rbn;
}
if(node < rbn->value){
return find(rbn->left,node);
} else {
return find(rbn->right,node);
}
}
lpRBNode minNode(lpRBNode node){
while (node->left !=nullptr){
node = node->left;
}
return node;
}
lpRBNode maxNode(lpRBNode node){
while (node->right !=nullptr){
node = node->right;
}
return node;
}
lpRBNode findPrecursor(lpRBNode node){
if(node->left != nullptr){
return maxNode(node->left);
} else {
lpRBNode pp;
while (node->father != nullptr){
pp = node->father;
if(pp->left!=node){
return pp;
}
node = pp;
}
return nullptr;
}
}
lpRBNode findSuccessor(lpRBNode node){
if(node->right != nullptr){
return minNode(node->right);
} else {
lpRBNode pp;
while (node->father != nullptr){
pp = node->father;
if(pp->right!=node){
return pp;
}
node = pp;
}
return nullptr;
}
}
void remove_fix(lpRBNode& p){
if(p->color == 0){
p->color = 1;
return;
}
else if(p->father== nullptr)return;
else if (p->color == 1){
// 替换结点是其父结点的左子结点
if(p->father->left == p){
lpRBNode Sibl = p->father->right;
lpRBNode SL = p->father->right->left;
lpRBNode SR = p->father->right->right;
if(Sibl && Sibl->color == 0){
Sibl->color = 1;
p->father->color = 0;
leftRotate(p->father); // 不影响p节点
p->father->right->color = 0;
remove_fix(p->father);
} else if(Sibl && Sibl->color == 1){
if(SR && SR->color == 0){
Sibl->color = p->father->color;
p->father->color = 1;
SR->color = 1;
leftRotate(p->father);
} else if(((SR!=nullptr && SR->color == 1) || SR==nullptr) &&
SL && SL->color == 0){
Sibl->color = p->father->color;
SL->color = 1;
rightRotate(Sibl);// 转成上个if的情况
} else if((SR && SR->color == 1 &&
SL && SL->color == 1) ||
(SR==nullptr && SL== nullptr)) {
Sibl->color = 0;
remove_fix(p->father);
}
}
} else if(p->father->right == p){
lpRBNode Sibl = p->father->left;
lpRBNode SL = p->father->left->left;
lpRBNode SR = p->father->left->right;
if(Sibl && Sibl->color == 0){
Sibl->color = 1;
p->father->color = 0;
rightRotate(p->father);
p->father->left->color = 0;
remove_fix(p->father);
} else if(Sibl && Sibl->color == 1){ //兄弟节点为黑色结点
if(SL && SL->color==0){
Sibl->color = p->father->color;
p->father->color = 1;
SL->color = 1;
rightRotate(p->father);
} else if(((SL && SL->color == 1) || SL== nullptr) &&
SR && SR->color == 0){
Sibl->color = 0;
SR->color = 1;
leftRotate(p->father->left);// 左子结点就变成红色 跟上一种情况一样
p->father->left->color = p->father->color;
p->father->color = 1;
p->father->left->left->color = 1;
rightRotate(p->father);
} else if((SL && SL->color == 1 &&
SR && SR->color == 1)||
(SL == nullptr && SR== nullptr)){
Sibl->color = 0;
remove_fix(p->father);
}
}
}
}
}
void remove(lpRBNode& rbt,int node){
//先找到要删节点
lpRBNode targetNode = find(rbt,node);
if (targetNode == nullptr) {
std::cout<<"not found target node";
return;
};
lpRBNode successor;
// 没有子节点 直接删除
if (targetNode->left == nullptr && targetNode->right == nullptr){
successor = targetNode;
}
else if(targetNode->left == nullptr || targetNode->right == nullptr){
if(targetNode->left != nullptr){
successor = targetNode->left;
} else {
successor = targetNode->right;
}
}
// 找到后继的节点 删除该替换节点
else {
successor = findPrecursor(targetNode);
}
targetNode->value = successor->value;// 先把值替换过来
remove_fix(successor);// REW:
if(successor->father->left == successor){
successor->father->left = nullptr;
} else if(successor->father->right == successor) {
successor->father->right = nullptr;
}
while (rbt->father!=nullptr){
rbt=rbt->father;
}
}
int maxHeight(lpRBNode rbn){
if(rbn == nullptr){
return 0;
}
int lefHeight=maxHeight(rbn->left);
int rightHeight = maxHeight(rbn->right);
return lefHeight >= rightHeight ? lefHeight + 1 : rightHeight+1;
}
void show(lpRBNode rbn){
if (rbn == nullptr){
std::cout<<"red black tree is null"<<std::endl;
return;
}
int i = 0;
int height = maxHeight(rbn);
std::vector<int> indents;
std::vector<lpRBNode> printContainer = std::vector<lpRBNode>{rbn};
std::vector<lpRBNode> storeContainer;
std::cout<<"maxheight: "<<height<<std::endl;
for(i=height;i>0;i--){
int indent = 4*i + i;
std::string print;
print.assign(indent,' ');
for(auto rbd:printContainer){
if (rbd != nullptr) {
print += std::to_string(rbd->value) + '(' + std::to_string(rbd->color) + ')';
print.append(5, ' ');
storeContainer.push_back(rbd->left);
storeContainer.push_back(rbd->right);
} else {
print += " ";
print.append(5,' ');
// FIXME: 这里需要修改
storeContainer.push_back(nullptr);
storeContainer.push_back(nullptr);
}
}
printContainer.erase(printContainer.begin(),printContainer.end());
printContainer.swap(storeContainer);
print.erase(print.end()-5);
print.append(indent,' ');
std::cout<<print<<std::endl;
}
}
int main(){
std::vector<int> sv = std::vector<int>{16,36,19,31,20,30,10,15,25,40,22,18,29};
lpRBNode rbtree = build_rbt(sv); // fixme: insert done!
// std::cout<right->right->value;
remove(rbtree,22);
remove(rbtree,30);
remove(rbtree,19);
remove(rbtree,31);
remove(rbtree,36);
remove(rbtree,15);
remove(rbtree,25);
insert(rbtree,27);
insert(rbtree,26);
remove(rbtree,18);
show(rbtree);
// std::cout<
return 0;
}