笔者近来学习了一下红黑树,写出了初步代码。分享出来,同时这个代码并不保证没有bug,所以摆出来希望经过一番磨练。
#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<stdlib.h>
// 定义颜色
typedef enum ColorType {RED,BLACK} COLOR;
#define datatype int
typedef struct RBtree
{
COLOR color;
datatype data;
struct RBtree *parent;
struct RBtree *lchild, *rchild;
}RBtree;
// 包含一棵树的root指针和nil尾指针
typedef struct rbtree_rootandnil
{
RBtree *root;
RBtree *nil;
}TreeRN;
/*------函数声明------*/
TreeRN *initRBTree();
TreeRN *insertRBtreeFixup(TreeRN *T, RBtree *r);
TreeRN *insertRNtree(TreeRN *T, datatype i);
TreeRN *rightRotate(TreeRN *T, RBtree *r);
TreeRN *leftRotate(TreeRN *T, RBtree *r);
TreeRN *RBtransplant(TreeRN *T, RBtree *original, RBtree *replace);
TreeRN *RBtreeDeleteFix(TreeRN *T, RBtree *x);
TreeRN *RBtreeDelete(TreeRN *T, RBtree *r);
/*--------------------*/
/**********************
函数用途:初始化一棵红黑树
返回值 :树T
**********************/
TreeRN *initRBTree()
{
TreeRN *T = (TreeRN *)malloc(sizeof(TreeRN));
T->nil = (RBtree *)malloc(sizeof(RBtree));
T->nil->color = BLACK;
T->nil->parent = NULL;
T->nil->rchild = T->nil->lchild = NULL;
T->root = T->nil;
return T;
}
/**********************
函数用途:以某一结点进行左旋
返回值 :树T
**********************/
TreeRN *leftRotate(TreeRN *T, RBtree *r)
{
RBtree *y = r->rchild;
r->rchild = y->lchild;
if (y->lchild != T->nil)
y->lchild->parent = r;
y->parent = r->parent;
if (r->parent == T->nil)
T->root = y;
else if (r == r->parent->lchild)
r->parent->lchild = y;
else r->parent->rchild = y;
y->lchild = r;
r->parent = y;
return T;
}
// warning
/*左旋假设 r右孩子不是T->nil,根节点父节点为nil*/
/**********************
函数用途:以某一结点进行右旋
返回值 :树T
**********************/
TreeRN *rightRotate(TreeRN *T, RBtree *r)
{
RBtree *y = r->lchild;
r->lchild = y->rchild;
if (y->rchild != T->nil)
y->rchild->parent = r;
y->parent = r->parent;
if (r->parent == T->nil)
T->root = y;
else if (r == r->parent->lchild)
r->parent->lchild = y;
else r->parent->rchild = y;
y->rchild = r;
r->parent = y;
return T;
}
/**********************
函数用途:插入操作,像二叉搜索树类似的插入
返回值 :树T
**********************/
TreeRN *insertRNtree(TreeRN *T, datatype i)
{
RBtree *y = T->root;
RBtree *x = T->nil;
while (y != T->nil)
{
x = y;
if (i < y->data)
y = y->lchild;
else y = y->rchild;
}
y = (RBtree *)malloc(sizeof(RBtree));
y->data = i;
y->parent = x;
if (T->root == T->nil)
{
T->root = y;
}
else if (i < x->data)
x->lchild = y;
else x->rchild = y;
y->lchild = T->nil;
y->rchild = T->nil;
y->color = RED;
T = insertRBtreeFixup(T, y);
return T;
}
/**********************
函数用途:插入函数校准,使符合红黑树性质
返回值 :树T
**********************/
TreeRN *insertRBtreeFixup(TreeRN *T, RBtree *r)
{
RBtree *y;
while (r->parent->color == RED)
{
if (r->parent == r->parent->parent->lchild)
{
y = r->parent->parent->rchild;
if (y->color == RED)
{
r->parent->color = BLACK;
y->color = BLACK;
r->parent->parent->color = RED;
r = r->parent->parent;
}
else
{
if (r == r->parent->rchild)
{
r = r->parent;
T = leftRotate(T, r);
}
r->parent->color = BLACK;
r->parent->parent->color = RED;
T = rightRotate(T, r->parent->parent);
}
}
else // r父节点是爷爷的右孩子
{
y = r->parent->parent->lchild;
if (y->color == RED)
{
r->parent->color = BLACK;
y->color = BLACK;
r->parent->parent->color = RED;
r = r->parent->parent;
}
else
{
if (r == r->parent->lchild)
{
r = r->parent;
T = rightRotate(T, r);
}
r->parent->color = BLACK;
r->parent->parent->color = RED;
T = leftRotate(T, r->parent->parent);
}
}
}
T->root->color = BLACK;
return T;
}
/**********************
函数用途:以某一结点替代另一节点
返回值 :树T
**********************/
TreeRN *RBtransplant(TreeRN *T, RBtree *original, RBtree *replace)
{
if (original->parent == T->nil)
T->root = replace;
else if (original == original->parent->lchild)
original->parent->lchild = replace;
else original->parent->rchild = replace;
if (replace != T->nil)
{
replace->parent = original->parent;
}
return T;
}
/**********************
函数用途:红黑树中结点删除操作
返回值 :树T
**********************/
TreeRN *RBtreeDelete(TreeRN *T, RBtree *r)
{
RBtree *x, *y = r;
COLOR reserveColor = y->color;
if (y->lchild == T->nil)
{
x = r->rchild;
T = RBtransplant(T, r, r->rchild);
//x->parent = y;
}
else if (y->rchild == T->nil)
{
x = r->lchild;
T = RBtransplant(T, r, r->lchild);
}
else
{
y = r->rchild;
for (; y->lchild != T->nil; y = y->lchild);
reserveColor = y->color;
x = y->rchild;
if (y->parent == r)
x->parent = y;
else
{
T = RBtransplant(T, y, y->rchild);
y->rchild = r->rchild;
y->rchild->parent = y;
}
T = RBtransplant(T, r, y);
y->lchild = r->lchild;
y->lchild->parent = y;
y->color = r->color;
}
free(r);
if (reserveColor == BLACK)
T = RBtreeDeleteFix(T, x);
return T;
}
/**********************
函数用途:删除校准,使其再度符合红黑树性质
返回值 :树T
**********************/
TreeRN *RBtreeDeleteFix(TreeRN *T, RBtree *x)
{
RBtree *y;
while (x != T->root&&x->color == BLACK)
{
if (x == x->parent->lchild)
{
y = x->parent->rchild;
if (y->color == RED)
{
y->color = BLACK;
x->parent->color = RED;
T = leftRotate(T, x->parent);
y = x->parent->rchild;
}
if (y->lchild->color == BLACK && y->rchild->color == BLACK)
{
y->color = RED;
x = x->parent;
}
else
{
if (y->rchild->color == BLACK)
{
y->lchild->color = BLACK;
y->color = RED;
T = rightRotate(T, y);
y = x->parent->rchild;
}
y->color = x->parent->color;
x->parent->color = BLACK;
y->rchild->color = BLACK;
T = leftRotate(T, x->parent);
x = T->root;
}
}
else
{
y = x->parent->lchild;
if (y->color == RED)
{
y->color = BLACK;
x->parent->color = RED;
T = rightRotate(T, x->parent);
y = x->parent->lchild;
}
if (y->rchild->color == BLACK && y->lchild->color == BLACK)
{
y->color = RED;
x = x->parent;
}
else
{
if (y->lchild->color == BLACK)
{
y->rchild->color = BLACK;
y->color = RED;
T = leftRotate(T, y);
y = x->parent->lchild;
}
y->color = x->parent->color;
x->parent->color = BLACK;
y->lchild->color = BLACK;
T = rightRotate(T, x->parent);
x = T->root;
}
}
}
x->color = BLACK;
return T;
}
插入情况
删除情况