#include <stdio.h>
#include <stdlib.h>
#define BLACK 0
#define RED 1
typedef struct rbnode {
int color;
int key;
struct rbnode *parent;
struct rbnode *left;
struct rbnode *right;
} RBNode;
typedef RBNode *RBTree;
// 整一个空子节点,作为哨兵
RBNode Nil = {BLACK, 0, NULL, NULL, NULL};
RBNode *nil = &Nil;
RBNode *FindMin(RBTree rbt)
{
while (rbt != nil && rbt->left != nil) {
rbt = rbt->left;
}
return rbt;
}
RBNode *FindPos(RBTree rbt, int key)
{
// if (rbt == nil)
// return nil;
//
// if (key < rbt->key)
// return FindPos(rbt->left, key);
// else if (key > rbt->key)
// return FindPos(rbt->right, key);
// else
// return rbt;
while (rbt != nil && key != rbt->key) {
if (key < rbt->key)
rbt = rbt->left;
else/* if (e > t->e) */
rbt = rbt->right;
}
return rbt;
}
// 使x成为左孩子
// y = x->right
// x->right = y->left
// y->left = x
RBTree LeftRotate(RBTree rbt, RBNode *x)
{
RBNode *y = x->right; // set y
x->right = y->left; // turn y's left subtree into x's right subtree
if (y->left != nil)
y->left->parent = x;
y->parent = x->parent; // link x's parent to y
if (x->parent == nil) // x为根(root)
rbt = y;
else if (x == x->parent->left) // 确定x为父亲的左孩子还是右孩子
x->parent->left = y;
else
x->parent->right = y;
y->left = x; // put x on y's left
x->parent = y;
return rbt;
}
// 使y成为右孩子
// x = y->left
// y->left = x->right
// x->right = y
RBTree RightRotate(RBTree rbt, RBNode *y)
{
RBNode *x = y->left;
y->left = x->right;
if (x->right != nil)
x->right->parent = y;
x->parent = y->parent;
if (y->parent == nil)
rbt = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
x->right = y;
y->parent = x;
return rbt;
}
RBTree RBInsertFixup(RBTree rbt, RBNode *z, RBNode *y)
{
/*RBNode *y = nil; // */
while (z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
y = z->parent->parent->right;
if (y->color == RED) { // case 1
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent; // 更新z的位置
} else {
if (z == z->parent->right) { // 右孩子
z = z->parent; // 更新z的位置
if (z->right != nil)
rbt = LeftRotate(rbt, z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
if (z->parent->parent->left != nil)
rbt = RightRotate(rbt, z->parent->parent);
}
} else {
y = z->parent->parent->left;
if (y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->left){
z = z->parent;
if (z->right != nil)
rbt = LeftRotate(rbt, z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
if (z->parent->parent->left != nil)
rbt = RightRotate(rbt, z->parent->parent);
}
}
}
rbt->color = BLACK;
return rbt;
}
RBTree RBInsert(RBTree rbt, RBNode *z)
{
RBNode *y = nil;
RBNode *x = rbt;
while (x != nil) { // 找到插入点
y = x; // 记录父节点
if (z->key < x->key)
x = x->left;
else
x = x->right;
}
z->parent = y; // 确定z的父节点,进行插入
if (y == nil) // z为新的根节点
rbt = z;
else if (z->key < y->key) // 确定z为y的左孩子还是有孩子
y->left = z;
else /*if (z->key >= y->key)*/
y->right = z;
z->left = nil;
z->right = nil;
z->color = RED;
rbt = RBInsertFixup(rbt, z, y);
return rbt;
}
RBTree RBTransplant(RBTree rbt, RBNode *u, RBNode *v)
{
if (u->parent == nil)
rbt = v;
else if (u == u->parent->left) // 左孩子
u->parent->left = v;
else
u->parent->right = v; // 右孩子
v->parent = u->parent;
return rbt;
}
RBTree RBDelectFixup(RBTree rbt, RBNode *x)
{
RBNode *w;
while (x != rbt && x->color == BLACK) {
if (x == x->parent->left) { // 左孩子
w = x->parent->right; // x的兄弟
if (w->color == RED) { // case 1
w->color = BLACK;
x->parent->color = RED;
if (x->parent->right != nil)
rbt = LeftRotate(rbt, x->parent);
w = x->parent->right;
}
if (w->left->color == BLACK && w->right->color == BLACK) { // case 2
w->color = RED;
x = x->parent;
} else {
if (w->right->color == BLACK) { // case 3
w->left->color = BLACK;
w->color = RED;
if (w->left != nil)
rbt = RightRotate(rbt, w);
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->right->color = BLACK;
if (x->parent->right != nil)
rbt = LeftRotate(rbt, x->parent);
x = rbt;
}
} else { // x == x->parent->left // 修改包括旋转的方向
w = x->parent->left; // x的兄弟
if (w->color == RED) { // case 1
w->color = BLACK;
x->parent->color = RED;
if (x->parent->left != nil)
rbt = RightRotate(rbt, x->parent);
w = x->parent->left;
}
if (w->left->color == BLACK && w->right->color == BLACK) { // case 2
w->color = RED;
x = x->parent;
} else {
if (w->left->color == BLACK) { // case 3
w->right->color = BLACK;
w->color = RED;
if (w->right != nil)
rbt = LeftRotate(rbt, w);
}
w->color = x->parent->color; // case 4
x->parent->color = BLACK;
w->left->color = BLACK;
if (x->parent->left != nil)
rbt = RightRotate(rbt, x->parent);
x = rbt;
}
}
}
x->color = BLACK;
return rbt;
}
RBTree RBDelect(RBTree rbt, RBNode *z)
{
RBNode *x;
RBNode *y = z;
int yoclr = y->color; // y-original-color
if (z->left == nil) { // 没有左孩子
x = z->right;
rbt = RBTransplant(rbt, z, z->right);
} else if (z->right == nil) { // 没有右孩子
x = z->left;
rbt = RBTransplant(rbt, z, z->left);
} else { // 有两个孩子
y = FindMin(z->right);
yoclr = y->color;
x = y->right;
if (y->parent == z) {
x->parent = y;
} else {
RBTransplant(rbt, y, y->right);
y->right = z->right;
y->right->parent = y;
}
rbt = RBTransplant(rbt, z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
free(z);
}
if (yoclr == BLACK)
rbt = RBDelectFixup(rbt, x);
return rbt;
}
void PreorderPrint(RBTree rbt)
{
if (rbt != nil) {
printf("%d\t", rbt->key);
PreorderPrint(rbt->left);
PreorderPrint(rbt->right);
}
}
void InorderPrint(RBTree rbt)
{
if (rbt != nil) {
InorderPrint(rbt->left);
printf("%d\t", rbt->key);
InorderPrint(rbt->right);
}
}
void PostorderPrint(RBTree rbt)
{
if (rbt != nil) {
PostorderPrint(rbt->left);
PostorderPrint(rbt->right);
printf("%d\t", rbt->key);
}
}
int main()
{
int arr[] = {19, 13, 23, 8, 17, 21, 43, 3, 11, 14};
int len = sizeof(arr) / sizeof(arr[0]);
RBTree rbt = nil;
for (int i = 0; i < len; i++) {
RBNode *x = (RBNode *)malloc(sizeof(RBNode));
if (!x) {
printf("x malloc error\n");
return -1;
}
x->key = arr[i];
x->parent = x->left = x->right = nil;
rbt = RBInsert(rbt, x);
}
printf("preorder:\n");
PreorderPrint(rbt);
printf("\n");
printf("inorder:\n");
InorderPrint(rbt);
printf("\n");
printf("postorder:\n");
PostorderPrint(rbt);
printf("\n");
for (int i = 0; i < len; i++) {
rbt = RBDelect(rbt, FindPos(rbt, arr[i]));
printf("inorder:\n");
InorderPrint(rbt);
printf("\n");
}
system("pause");
return 0;
}