插入元素
情况1:插入结点为根
直接染黑
情况2:插入结点父亲为黑
不进行任何操作
情况3:插入结点父亲为红,叔叔为红
爷爷染红,父亲和叔叔染黑,把爷爷视为新结点继续判断
情况4:插入结点父亲为红,叔叔为黑
情况4-1:LL型
父亲和爷爷右旋,父亲染黑,爷爷染红
情况4-2:LR型
插入结点和父亲左旋,转化为情况4-1
情况4-3:RR型
父亲和爷爷左旋,父亲染黑,爷爷染红
情况4-4:RL型
插入结点与父亲右旋,转化为情况4-3
删除元素
情况1:删除结点左右孩子均不为空
找到直接前驱,关键字赋值给删除结点,然后将直接前驱(最多有一个不为空的孩子)视为新的删除结点,此时问题被转化为了其它情况
情况2:删除结点为红
此时该结点左右孩子一定为空结点,直接删除该结点
情况3:删除结点为黑,儿子为红
儿子顶替删除结点,然后染红
情况4:删除结点为黑,儿子为黑
情况4最为复杂,单独讨论,此时儿子结点一定为空节点
情况4-1:删除结点是根结点
初始化红黑树
情况4-2:兄弟为红
父亲和兄弟旋转变换,兄弟成为祖父,祖父和父亲颜色对换,将问题转换为其它情况
情况4-3:父亲为黑,兄弟为黑,侄子为黑
兄弟染红将问题转换位其他情况
情况4-4:父亲为红,兄弟为黑,侄子为黑
父亲染黑,兄弟染红
情况4-5:左兄弟为黑,左侄子为红,右侄子为黑
兄弟和兄弟红孩子旋转对换颜色变为其它情况
情况4-6:右兄弟为黑,右侄子为红
父亲和兄弟左旋对换颜色
完整实现代码
#include <stdio.h>
#include <stdlib.h>
//颜色
typedef enum Color {
red,
black
} Color;
//红黑树结点
typedef struct RBTNode {
int key; //关键字
int color; //颜色
struct RBTNode *parent; //双亲
struct RBTNode *lChild; //左孩子
struct RBTNode *rChild; //右孩子
} RBTNode;
//红黑树
typedef struct RBT {
RBTNode *root; //根结点
RBTNode *nil; //引入nil结点
} RBT;
//获取爷爷结点
RBTNode *grandparent(const RBTNode *p) {
return p->parent->parent;
}
//获取叔叔结点
RBTNode *uncle(const RBTNode *p) {
if (grandparent(p)->lChild == p->parent) {
return grandparent(p)->rChild;
}
return grandparent(p)->lChild;
}
//获取兄弟结点
RBTNode *brother(const RBTNode *p) {
if (p->parent->lChild == p) {
return p->parent->rChild;
}
return p->parent->lChild;
}
//获取直接前驱
RBTNode *precursor(const RBT *rbt, RBTNode *p) {
p = p->lChild;
while (p->rChild != rbt->nil) {
p = p->rChild;
}
return p;
}
//左旋
void leftRotate(RBT *rbt, RBTNode *p) {
RBTNode *rChild = p->rChild;
p->rChild = rChild->lChild;
if (rChild->lChild != rbt->nil) {
rChild->lChild->parent = p;
}
rChild->parent = p->parent;
if (p->parent->lChild == p) {
p->parent->lChild = rChild;
} else if (p->parent->rChild == p) {
p->parent->rChild = rChild;
} else {
rbt->root = rChild;
}
rChild->lChild = p;
p->parent = rChild;
}
//右旋
void rightRotate(RBT *rbt, RBTNode *p) {
RBTNode *lChild = p->lChild;
p->lChild = lChild->rChild;
if (lChild->rChild != rbt->nil) {
lChild->rChild->parent = p;
}
lChild->parent = p->parent;
if (p->parent->lChild == p) {
p->parent->lChild = lChild;
} else if (p->parent->rChild == p) {
p->parent->rChild = lChild;
} else {
rbt->root = lChild;
}
lChild->rChild = p;
p->parent = lChild;
}
//创建
RBTNode *createRBTNode(int key, Color color, RBTNode *parent, RBTNode *lChild, RBTNode *rChild) {
RBTNode *node = (RBTNode *) malloc(sizeof(RBTNode));
node->key = key;
node->color = color;
node->parent = parent;
node->lChild = lChild;
node->rChild = rChild;
return node;
}
//初始化
void initRBT(RBT *rbt) {
rbt->nil = createRBTNode(0, black, NULL, NULL, NULL);
rbt->nil->parent = rbt->root = rbt->nil;
}
//查找
bool searchRBT(const RBT *rbt, int key, RBTNode **pp) {
RBTNode *p = *pp = rbt->root;
while (p != rbt->nil) {
*pp = p;
if (p->key > key) {
p = p->lChild;
} else if (p->key < key) {
p = p->rChild;
} else {
return true;
}
}
return false;
}
//插入操作后修复
void insertFix(RBT *rbt, RBTNode *p) {
while (p->parent->color == red) {
if (p->parent == p->parent->parent->lChild) {
if (uncle(p)->color == red) {
p->parent->color = black;
grandparent(p)->color = red;
uncle(p)->color = black;
p = grandparent(p);
} else {
if (p == p->parent->rChild) {
p = p->parent;
leftRotate(rbt, p);
}
rightRotate(rbt, grandparent(p));
p->parent->color = black;
brother(p)->color = red;
}
} else {
if (uncle(p)->color == red) {
p->parent->color = black;
grandparent(p)->color = red;
uncle(p)->color = black;
p = grandparent(p);
} else {
if (p == p->parent->lChild) {
p = p->parent;
rightRotate(rbt, p);
}
leftRotate(rbt, grandparent(p));
p->parent->color = black;
brother(p)->color = red;
}
}
}
rbt->root->color = black;
}
//插入
void insertRBT(RBT *rbt, int key) {
RBTNode *p = rbt->nil;
if (searchRBT(rbt, key, &p)) {
printf("结点已存在!\n");
return;
}
RBTNode *node = createRBTNode(key, red, p, rbt->nil, rbt->nil);
if (p == rbt->nil) {
rbt->root = node;
} else if (p->key > key) {
p->lChild = node;
} else {
p->rChild = node;
}
insertFix(rbt, node);
}
//删除复杂的情况
void deleteDifficult(RBT *rbt, RBTNode *p) {
if (p->parent == rbt->nil) {
p->color = black;
return;
}
if (brother(p)->color == red) {
p->parent->color = red;
brother(p)->color = black;
if (p == p->parent->lChild) {
leftRotate(rbt, p->parent);
} else {
rightRotate(rbt, p->parent);
}
}
if (p->parent->color == black && brother(p)->color == black && brother(p)->lChild->color == black &&
brother(p)->rChild->color == black) {
brother(p)->color = red;
deleteDifficult(rbt, p->parent);
} else if (p->parent->color == red && brother(p)->color == black && brother(p)->lChild->color == black &&
brother(p)->rChild->color == black) {
brother(p)->color = red;
p->parent->color = black;
} else {
if (brother(p)->color == black) {
if (p == p->parent->lChild && brother(p)->lChild->color == red && brother(p)->rChild->color == black) {
brother(p)->color = red;
brother(p)->lChild->color = black;
rightRotate(rbt, brother(p)->lChild);
} else if (p == p->parent->rChild && brother(p)->lChild->color == black &&
brother(p)->rChild->color == red) {
brother(p)->color = red;
brother(p)->rChild->color = black;
leftRotate(rbt, brother(p)->rChild);
}
}
brother(p)->color = p->parent->color;
p->parent->color = black;
if (p == p->parent->lChild) {
brother(p)->rChild->color = black;
leftRotate(rbt, brother(p));
} else {
brother(p)->lChild->color = black;
rightRotate(rbt, brother(p));
}
}
}
//删除只有一个孩子的结点
void deleteOneChild(RBT *rbt, RBTNode *p) {
RBTNode *child = p->lChild == rbt->nil ? p->rChild : p->lChild;
if (p->parent == rbt->nil && p->lChild == rbt->nil && p->rChild == rbt->nil) {
rbt->root = rbt->nil;
} else if (p->parent == rbt->nil) {
child->color = black;
child->parent = rbt->nil;
rbt->root = child;
} else {
if (p->parent->lChild == p) {
p->parent->lChild = child;
} else {
p->parent->rChild = child;
}
child->parent = p->parent;
if (p->color == black) {
if (child->color == red) {
child->color = black;
} else {
deleteDifficult(rbt, child);
}
}
}
free(p);
}
//删除
void deleteRBT(RBT *rbt, int key) {
RBTNode *p = rbt->nil;
if (!searchRBT(rbt, key, &p)) {
printf("结点不存在!\n");
return;
}
if (p->lChild != rbt->nil && p->rChild != rbt->nil) {
p->key = precursor(rbt, p)->key;
p = precursor(rbt, p);
}
deleteOneChild(rbt, p);
}
//中序遍历
void inorderRBT(const RBTNode *p, RBTNode *nil) {
if (p != nil) {
inorderRBT(p->lChild, nil);
printf("%-10d", p->key);
if (p->color == red) {
printf("%-10s", "红色");
} else {
printf("%-10s", "黑色");
}
if (p->lChild != nil) {
printf("%-10d", p->lChild->key);
} else {
printf("%-10s", "无");
}
if (p->rChild != nil) {
printf("%-10d", p->rChild->key);
} else {
printf("%-10s", "无");
}
if (p->parent != nil) {
printf("%-10d\n", p->parent->key);
} else {
printf("%-10s\n", "无");
}
inorderRBT(p->rChild, nil);
}
}
//测试代码
void test() {
RBT rbt;
initRBT(&rbt);
int sel, key;
while (true) {
printf("1.插入数据\n2.删除数据\n3.打印信息\n");
scanf("%d", &sel);
switch (sel) {
case 1: {
printf("关键字:");
scanf("%d", &key);
insertRBT(&rbt, key);
break;
}
case 2: {
printf("关键字:");
scanf("%d", &key);
deleteRBT(&rbt, key);
break;
}
case 3: {
printf("%-10s%-10s%-10s%-10s%-10s\n", "关键字", "颜色", "左孩子", "右孩子", "双亲");
inorderRBT(rbt.root, rbt.nil);
break;
}
default:
return;
}
system("pause");
system("cls");
}
}
//主函数
int main() {
test();
return 0;
}