#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; }